summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 8fdd9fd)
raw | patch | inline | side by side (parent: 8fdd9fd)
author | Ketmar Dark <ketmar@ketmar.no-ip.org> | |
Sat, 12 Oct 2019 01:47:26 +0000 (04:47 +0300) | ||
committer | Ketmar Dark <ketmar@ketmar.no-ip.org> | |
Sat, 12 Oct 2019 15:54:12 +0000 (18:54 +0300) |
src/game/g_net.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_net.pas b/src/game/g_net.pas
index 251e06bb213071c07a958e9d2f0a4741b3b4cedd..db8db654355b63265729be6574a70106b1068872 100644 (file)
--- a/src/game/g_net.pas
+++ b/src/game/g_net.pas
lastAckTime: Int64; // msecs; if not "in progress", we're waiting for the first ack
inProgress: Boolean;
diskBuffer: PChar; // of `chunkSize` bytes
+ resumed: Boolean;
end;
TNetClient = record
chunk: Integer;
csize: Integer;
buf: PChar = nil;
+ resumed: Boolean;
//stx: Int64;
begin
+ tf.resumed := false;
+ e_LogWritefln('file `%s`, size=%d (%d)', [tf.diskName, Integer(strm.size), tf.size], TMsgType.Notify);
+ // check if we should resume downloading
+ resumed := (strm.size > tf.chunkSize) and (strm.size < tf.size);
// send request
trans_omsg.Clear();
trans_omsg.Write(Byte(NTF_CLIENT_START));
- trans_omsg.Write(LongInt(0));
+ if resumed then chunk := strm.size div tf.chunkSize else chunk := 0;
+ trans_omsg.Write(LongInt(chunk));
if not ftransSendClientMsg(trans_omsg) then begin result := -1; exit; end;
+ strm.Seek(chunk*tf.chunkSize, soFromBeginning);
chunkTotal := (tf.size+tf.chunkSize-1) div tf.chunkSize;
e_LogWritefln('receiving file `%s` (%d chunks)', [tf.diskName, chunkTotal], TMsgType.Notify);
g_Game_SetLoadingText('downloading "'+ExtractFileName(tf.diskName)+'"', chunkTotal, False);
+ tf.resumed := resumed;
+
+ if (chunk > 0) then g_Game_StepLoading(chunk);
+ nextChunk := chunk;
// wait for reply data
FillChar(ev, SizeOf(ev), 0);
index ae645a1196677443c505ee10f75dcd0e16f63193..b2844c651539202b622fdcdea8e46fd063b60652 100644 (file)
strm: TStream;
fname: AnsiString;
wadname: AnsiString;
+ md5: TMD5Digest;
begin
//SetLength(mapData.ExternalResources, 0);
result := '';
end;
fname := GameDir+'/maps/downloads/'+FileName;
try
- strm := createDiskFile(fname);
+ strm := openDiskFileRW(fname);
except
e_WriteLog('cannot create map file `'+FileName+'`', TMsgType.Fatal);
result := '';
result := '';
exit;
end;
+ // if it was resumed, check md5 and initiate full download if necessary
+ if tf.resumed then
+ begin
+ md5 := MD5File(fname);
+ // sorry for pasta, i am asshole
+ if not MD5Match(md5, tf.hash) then
+ begin
+ e_LogWritefln('resuming failed; downloading map `%s` from scratch...', [fname]);
+ try
+ DeleteFile(fname);
+ strm := createDiskFile(fname);
+ except
+ e_WriteLog('cannot create map file `'+fname+'`', TMsgType.Fatal);
+ result := '';
+ exit;
+ end;
+ try
+ res := g_Net_ReceiveResourceFile(-1{map}, tf, strm);
+ except
+ e_WriteLog('error downloading map file `'+FileName+'`', TMsgType.Fatal);
+ strm.Free;
+ result := '';
+ exit;
+ end;
+ strm.Free;
+ if (res <> 0) then
+ begin
+ e_WriteLog('error downloading map file `'+FileName+'`', TMsgType.Fatal);
+ result := '';
+ exit;
+ end;
+ end;
+ end;
result := fname;
end;
fname := GameDir+'/wads/downloads/'+tf.diskName;
e_LogWritefln('downloading resource `%s` to `%s`...', [tf.diskName, fname]);
try
- strm := createDiskFile(fname);
+ strm := openDiskFileRW(fname);
except
e_WriteLog('cannot create resource file `'+fname+'`', TMsgType.Fatal);
result := '';
result := '';
exit;
end;
+ // if it was resumed, check md5 and initiate full download if necessary
+ if tf.resumed then
+ begin
+ md5 := MD5File(fname);
+ // sorry for pasta, i am asshole
+ if not MD5Match(md5, tf.hash) then
+ begin
+ e_LogWritefln('resuming failed; downloading resource `%s` to `%s` from scratch...', [tf.diskName, fname]);
+ try
+ DeleteFile(fname);
+ strm := createDiskFile(fname);
+ except
+ e_WriteLog('cannot create resource file `'+fname+'`', TMsgType.Fatal);
+ result := '';
+ exit;
+ end;
+ try
+ res := g_Net_ReceiveResourceFile(f, tf, strm);
+ except
+ e_WriteLog('error downloading map file `'+FileName+'`', TMsgType.Fatal);
+ strm.Free;
+ result := '';
+ exit;
+ end;
+ strm.Free;
+ if (res <> 0) then
+ begin
+ e_WriteLog('error downloading map file `'+FileName+'`', TMsgType.Fatal);
+ result := '';
+ exit;
+ end;
+ end;
+ end;
g_Res_PutReplacementWad(tf.diskName, fname);
end;
end;
diff --git a/src/shared/utils.pas b/src/shared/utils.pas
index a854ca45bc922f155465ed98a32daad0710ced8c..215e60a8115bfb5373da9329867f78804a001139 100644 (file)
--- a/src/shared/utils.pas
+++ b/src/shared/utils.pas
// they throws
function openDiskFileRO (pathname: AnsiString): TStream;
function createDiskFile (pathname: AnsiString): TStream;
+// creates file if necessary
+function openDiskFileRW (pathname: AnsiString): TStream;
// little endian
procedure writeSign (st: TStream; const sign: AnsiString);
end;
+function openDiskFileRW (pathname: AnsiString): TStream;
+var
+ path: AnsiString;
+ oldname: AnsiString;
+begin
+ //writeln('*** TRYING R/W FILE "', pathname, '"');
+ path := ExtractFilePath(pathname);
+ if length(path) > 0 then
+ begin
+ if not findFileCI(path, true) then raise Exception.Create('can''t create file "'+pathname+'"');
+ end;
+ oldname := pathname;
+ if findFileCI(oldname) then
+ begin
+ //writeln('*** found old file "', oldname, '"');
+ result := TFileStream.Create(oldname, fmOpenReadWrite or fmShareDenyWrite);
+ end
+ else
+ begin
+ result := TFileStream.Create(path+ExtractFileName(pathname), fmCreate);
+ end;
+end;
+
+
procedure writeIntegerLE (st: TStream; vp: Pointer; size: Integer);
{$IFDEF ENDIAN_LITTLE}
begin