From bec8cdb3ed10342622663c441db86cbd7bb63885 Mon Sep 17 00:00:00 2001 From: Ketmar Dark Date: Sat, 12 Oct 2019 01:27:25 +0300 Subject: [PATCH] net: more code for file transfers; it was able to transfer a map, and even substiture resource wads --- src/game/g_map.pas | 36 +++++++++++++++++++++++++++-------- src/game/g_net.pas | 34 +++++++++++++++++++++++++-------- src/game/g_res_downloader.pas | 20 ++++++++++++++----- 3 files changed, 69 insertions(+), 21 deletions(-) diff --git a/src/game/g_map.pas b/src/game/g_map.pas index bf1f915..08ebade 100644 --- a/src/game/g_map.pas +++ b/src/game/g_map.pas @@ -259,7 +259,8 @@ uses Math, g_monsters, g_saveload, g_language, g_netmsg, sfs, xstreams, hashtable, wadreader, ImagingTypes, Imaging, ImagingUtility, - ImagingGif, ImagingNetworkGraphics; + ImagingGif, ImagingNetworkGraphics, + g_res_downloader; const FLAGRECT: TRectWH = (X:15; Y:12; Width:33; Height:52); @@ -899,6 +900,26 @@ begin end; +function GetReplacementWad (WadName: AnsiString): AnsiString; +begin + if (length(WadName) = 0) then + begin + result := ''; + end + else + begin + result := g_Res_FindReplacementWad(WadName); + if (result <> WadName) then + begin + //e_LogWritefln('GetReplacementWad: old=%s; new=%s', [WadName, result]); + end + else + begin + result := GameDir+'/wads/'+result; + end; + end; +end; + function CreateTexture(RecName: AnsiString; Map: string; log: Boolean): Integer; var WAD: TWADFile; @@ -957,12 +978,10 @@ begin end; // Çàãðóæàåì ðåñóðñ òåêñòóðû â ïàìÿòü èç WAD'à: - WADName := g_ExtractWadName(RecName); + WADName := GetReplacementWad(g_ExtractWadName(RecName)); + if WADName = '' then WADName := Map; //WADName := GameDir+'/wads/'+WADName else WAD := TWADFile.Create(); - - if WADName <> '' then WADName := GameDir+'/wads/'+WADName else WADName := Map; - WAD.ReadFile(WADName); //txname := RecName; @@ -1045,11 +1064,12 @@ begin end; // ×èòàåì WAD-ðåñóðñ àíèì.òåêñòóðû èç WAD'à â ïàìÿòü: - WADName := g_ExtractWadName(RecName); + WADName := GetReplacementWad(g_ExtractWadName(RecName)); + if WADName = '' then WADName := Map; //WADName := GameDir+'/wads/'+WADName else WAD := TWADFile.Create(); try - if WADName <> '' then WADName := GameDir+'/wads/'+WADName else WADName := Map; + //if WADName <> '' then WADName := GameDir+'/wads/'+WADName else WADName := Map; WAD.ReadFile(WADName); @@ -1451,7 +1471,7 @@ begin //e_LogWritefln('DBG: ***trying external resource %s', [res]); res := toLowerCase1251(extractWadName(res)); // ignore "standart.wad" - if (res <> '') and (res <> 'standart.wad') and (gExternalResources.IndexOf(res) = -1) then + if (res <> '') {and (res <> 'standart.wad')} and (gExternalResources.IndexOf(res) = -1) then begin //e_LogWritefln('DBG: added external resource %s', [res]); gExternalResources.Add(res); diff --git a/src/game/g_net.pas b/src/game/g_net.pas index 82f4632..ac84585 100644 --- a/src/game/g_net.pas +++ b/src/game/g_net.pas @@ -721,7 +721,7 @@ begin rd := tf.size-(tf.lastSentChunk*tf.chunkSize); if (rd > tf.chunkSize) then rd := tf.chunkSize; omsg.Write(LongInt(rd)); - e_LogWritefln('download: client #%d, sending chunk #%d/#%d (%d bytes)', [nc.ID, tf.lastSentChunk, chunks, rd]); + //e_LogWritefln('download: client #%d, sending chunk #%d/#%d (%d bytes)', [nc.ID, tf.lastSentChunk, chunks, rd]); //FIXME: check for errors here try tf.stream.Seek(tf.lastSentChunk*tf.chunkSize, soFromBeginning); @@ -773,14 +773,13 @@ begin for f := Low(NetClients) to High(NetClients) do begin if (not NetClients[f].Used) then continue; - //if (NetClients[f].Transfer.stream = nil) then continue; if (NetClients[f].Peer = NetEvent.peer) then begin nid := f; break; end; end; - e_LogWritefln('RECEIVE: dlpacket; client=%d (datalen=%u)', [nid, NetEvent.packet^.dataLength]); + //e_LogWritefln('RECEIVE: dlpacket; client=%d (datalen=%u)', [nid, NetEvent.packet^.dataLength]); if (nid < 0) then exit; // wtf?! nc := @NetClients[nid]; @@ -795,7 +794,7 @@ begin tf.lastAckTime := GetTimerMS(); cmd := Byte(NetEvent.packet^.data^); - e_LogWritefln('RECEIVE: nid=%d; cmd=%u', [nid, cmd]); + //e_LogWritefln('RECEIVE: nid=%d; cmd=%u', [nid, cmd]); case cmd of NTF_CLIENT_FILE_REQUEST: // file request begin @@ -823,7 +822,7 @@ begin KillClientByFT(nc^); exit; end; - if (ridx < 0) then fname := MapsDir+gGameSettings.WAD else fname := gExternalResources[ridx]; + if (ridx < 0) then fname := MapsDir+gGameSettings.WAD else fname := GameDir+'/wads/'+gExternalResources[ridx]; if (length(fname) = 0) then begin e_WriteLog('Invalid filename: '+fname, TMsgType.Warning); @@ -831,7 +830,7 @@ begin exit; end; tf.diskName := findDiskWad(fname); - if (length(tf.diskName) = 0) then tf.diskName := findDiskWad(GameDir+'/wads/'+fname); + //if (length(tf.diskName) = 0) then tf.diskName := findDiskWad(GameDir+'/wads/'+fname); if (length(tf.diskName) = 0) then begin e_LogWritefln('NETWORK: file "%s" not found!', [fname], TMsgType.Fatal); @@ -960,7 +959,7 @@ begin // do it this way, so client may seek, or request retransfers for some reason tf.lastAckChunk := chunk; tf.lastSentChunk := chunk; - e_LogWritefln('client #%d acked file transfer chunk %d', [nc.ID, chunk]); + //e_LogWritefln('client #%d acked file transfer chunk %d', [nc.ID, chunk]); end; NTF_CLIENT_MAP_REQUEST: begin @@ -1015,6 +1014,7 @@ var TC: pTNetClient; TP: TPlayer; f: Integer; + //ctt: Int64; begin IP := ''; Result := 0; @@ -1022,6 +1022,7 @@ begin if NetUseMaster then g_Net_Slist_Check; g_Net_Host_CheckPings; + //ctt := -GetTimerMS(); // process file transfers for f := Low(NetClients) to High(NetClients) do begin @@ -1029,6 +1030,10 @@ begin if (NetClients[f].Transfer.stream = nil) then continue; ProcessHostFileTransfers(NetClients[f]); end; + { + ctt := ctt+GetTimerMS(); + if (ctt > 1) then e_LogWritefln('all transfers: [%d]', [Integer(ctt)]); + } while (enet_host_service(NetHost, @NetEvent, 0) > 0) do begin @@ -1925,10 +1930,12 @@ var ct, ett: Int64; status: cint; nextChunk: Integer = 0; + chunkTotal: Integer; chunk: Integer; csize: Integer; buf: PChar = nil; pkt: PENetPacket; + //stx: Int64; begin // send request msg.Alloc(NET_BUFSIZE); @@ -1943,6 +1950,10 @@ begin msg.Free(); end; + 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); + // wait for reply data FillChar(ev, SizeOf(ev), 0); Result := -1; @@ -1950,6 +1961,7 @@ begin try ett := getNewTimeoutEnd(); repeat + //stx := -GetTimerMS(); status := enet_host_service(NetHost, @ev, 300); if (status < 0) then begin @@ -1984,6 +1996,9 @@ begin end else begin + //stx := stx+GetTimerMS(); + //e_LogWritefln('g_Net_ReceiveResourceFile: stx=%d', [Integer(stx)]); + //stx := -GetTimerMS(); ett := getNewTimeoutEnd(); if (ev.packet.dataLength < 1) then begin @@ -2016,10 +2031,11 @@ begin Result := -1; exit; end; - e_LogWritefln('got chunk #%d of #%d (csize=%d)', [chunk, (tf.size+tf.chunkSize-1) div tf.chunkSize, csize]); + //e_LogWritefln('got chunk #%d of #%d (csize=%d)', [chunk, (tf.size+tf.chunkSize-1) div tf.chunkSize, csize]); msg.ReadData(buf, csize); strm.WriteBuffer(buf^, csize); nextChunk := chunk+1; + g_Game_StepLoading(); // send ack omsg.Alloc(NET_BUFSIZE); try @@ -2045,6 +2061,8 @@ begin Result := -1; exit; end; + //stx := stx+GetTimerMS(); + //e_LogWritefln('g_Net_ReceiveResourceFile: process stx=%d', [Integer(stx)]); end; end; ENET_EVENT_TYPE_DISCONNECT: diff --git a/src/game/g_res_downloader.pas b/src/game/g_res_downloader.pas index ed1ea3b..7271757 100644 --- a/src/game/g_res_downloader.pas +++ b/src/game/g_res_downloader.pas @@ -20,7 +20,6 @@ interface uses sysutils, Classes, md5, g_net, g_netmsg, g_console, g_main, e_log; function g_Res_SearchSameWAD(const path, filename: AnsiString; const resMd5: TMD5Digest): AnsiString; -function g_Res_SearchResWad (asMap: Boolean; const resMd5: TMD5Digest): AnsiString; // download map wad from server (if necessary) // download all required map resource wads too @@ -174,6 +173,7 @@ end; procedure g_Res_PutReplacementWad (oldname: AnsiString; newDiskName: AnsiString); begin e_LogWritefln('adding replacement wad: oldname=%s; newname=%s', [oldname, newDiskName]); + if not assigned(replacements) then replacements := THashStrStr.Create(); replacements.put(toLowerCase1251(oldname), newDiskName); end; @@ -237,7 +237,7 @@ begin end; -function g_Res_SearchResWad (asMap: Boolean; const resMd5: TMD5Digest): AnsiString; +function g_Res_SearchResWad (asMap: Boolean; fname: AnsiString; const resMd5: TMD5Digest): AnsiString; var f: Integer; begin @@ -245,10 +245,20 @@ begin //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); 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); end; for f := Low(knownFiles) to High(knownFiles) do @@ -283,7 +293,6 @@ var wadname: AnsiString; begin //SetLength(mapData.ExternalResources, 0); - //result := g_Res_SearchResWad(true{asMap}, mapHash); result := ''; g_Res_ClearReplacementWads(); g_Res_received_map_start := false; @@ -313,7 +322,7 @@ begin if (res <> 0) then exit; // find or download a map - result := g_Res_SearchResWad(true{asMap}, mapHash); + result := g_Res_SearchResWad(true{asMap}, tf.diskName, mapHash); if (length(result) = 0) then begin // download map @@ -332,6 +341,7 @@ begin result := ''; exit; end; + tf.diskName := fname; try res := g_Net_ReceiveResourceFile(-1{map}, tf, strm); except @@ -371,7 +381,7 @@ begin begin res := g_Net_RequestResFileInfo(f, tf); if (res <> 0) then begin result := ''; exit; end; - wadname := g_Res_SearchResWad(false{asMap}, tf.hash); + wadname := g_Res_SearchResWad(false{asMap}, tf.diskName, tf.hash); if (length(wadname) <> 0) then begin // already here -- 2.29.2