DEADSOFTWARE

net: nuked old commented out downloader code
[d2df-sdl.git] / src / game / g_net.pas
index 82f4632a28c22fefd344cdca1e406d3f547534e0..8f8488f904fad54e4e014f62db6a1afd15de329c 100644 (file)
@@ -21,7 +21,7 @@ uses
   e_log, e_msg, ENet, Classes, md5, MAPDEF{$IFDEF USE_MINIUPNPC}, miniupnpc;{$ELSE};{$ENDIF}
 
 const
-  NET_PROTOCOL_VER = 181;
+  NET_PROTOCOL_VER = 182;
 
   NET_MAXCLIENTS = 24;
   NET_CHANS = 12;
@@ -90,6 +90,7 @@ type
     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
@@ -181,7 +182,7 @@ var
 
   NetDumpFile: TStream;
 
-  g_Res_received_map_start: Boolean = false; // set if we received "map change" event
+  g_Res_received_map_start: Integer = 0; // set if we received "map change" event
 
 
 function  g_Net_Init(): Boolean;
@@ -249,6 +250,7 @@ const
 
 var
   g_Net_DownloadTimeout: Single;
+  trans_omsg: TMsg;
 
 
 { /// SERVICE FUNCTIONS /// }
@@ -670,17 +672,41 @@ begin
 end;
 
 
-procedure ProcessHostFileTransfers (var nc: TNetClient);
+function ftransSendServerMsg (var nc: TNetClient; var m: TMsg): Boolean;
+var
+  pkt: PENetPacket;
+begin
+  result := false;
+  if (m.CurSize < 1) then exit;
+  pkt := enet_packet_create(m.Data, m.CurSize, ENET_PACKET_FLAG_RELIABLE);
+  if not Assigned(pkt) then begin KillClientByFT(nc); exit; end;
+  if (enet_peer_send(nc.Peer, NET_CHAN_DOWNLOAD_EX, pkt) <> 0) then begin KillClientByFT(nc); exit; end;
+  result := true;
+end;
+
+
+function ftransSendClientMsg (var m: TMsg): Boolean;
+var
+  pkt: PENetPacket;
+begin
+  result := false;
+  if (m.CurSize < 1) then exit;
+  pkt := enet_packet_create(m.Data, m.CurSize, ENET_PACKET_FLAG_RELIABLE);
+  if not Assigned(pkt) then exit;
+  if (enet_peer_send(NetPeer, NET_CHAN_DOWNLOAD_EX, pkt) <> 0) then exit;
+  result := true;
+end;
+
+
+procedure ProcessChunkSend (var nc: TNetClient);
 var
   tf: ^TNetFileTransfer;
   ct: Int64;
   chunks: Integer;
   rd: Integer;
-  pkt: PENetPacket;
-  omsg: TMsg;
 begin
   tf := @nc.Transfer;
-  if (tf.stream = nil) then exit;;
+  if (tf.stream = nil) then exit;
   ct := GetTimerMS();
   // arbitrary timeout number
   if (ct-tf.lastAckTime >= 5000) then
@@ -702,51 +728,36 @@ begin
     exit;
   end;
 
-  omsg.Alloc(NET_BUFSIZE);
-  try
-    omsg.Clear();
-    if (tf.lastSentChunk = chunks) then
-    begin
-      // we're done with this file
-      e_LogWritefln('download: client #%d, DONE sending chunks #%d/#%d', [nc.ID, tf.lastSentChunk, chunks]);
-      omsg.Write(Byte(NTF_SERVER_DONE));
-      clearNetClientTransfers(nc);
-    end
-    else
-    begin
-      // packet type
-      omsg.Write(Byte(NTF_SERVER_CHUNK));
-      omsg.Write(LongInt(tf.lastSentChunk));
-      // read chunk
-      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]);
-      //FIXME: check for errors here
-      try
-        tf.stream.Seek(tf.lastSentChunk*tf.chunkSize, soFromBeginning);
-        tf.stream.ReadBuffer(tf.diskBuffer^, rd);
-        omsg.WriteData(tf.diskBuffer, rd);
-      except // sorry
-        KillClientByFT(nc);
-        exit;
-      end;
-    end;
-    // send packet
-    pkt := enet_packet_create(omsg.Data, omsg.CurSize, ENET_PACKET_FLAG_RELIABLE);
-    if not Assigned(pkt) then
-    begin
-      KillClientByFT(nc);
-      exit;
-    end;
-    if (enet_peer_send(nc.Peer, NET_CHAN_DOWNLOAD_EX, pkt) <> 0) then
-    begin
+  trans_omsg.Clear();
+  if (tf.lastSentChunk = chunks) then
+  begin
+    // we're done with this file
+    e_LogWritefln('download: client #%d, DONE sending chunks #%d/#%d', [nc.ID, tf.lastSentChunk, chunks]);
+    trans_omsg.Write(Byte(NTF_SERVER_DONE));
+    clearNetClientTransfers(nc);
+  end
+  else
+  begin
+    // packet type
+    trans_omsg.Write(Byte(NTF_SERVER_CHUNK));
+    trans_omsg.Write(LongInt(tf.lastSentChunk));
+    // read chunk
+    rd := tf.size-(tf.lastSentChunk*tf.chunkSize);
+    if (rd > tf.chunkSize) then rd := tf.chunkSize;
+    trans_omsg.Write(LongInt(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);
+      tf.stream.ReadBuffer(tf.diskBuffer^, rd);
+      trans_omsg.WriteData(tf.diskBuffer, rd);
+    except // sorry
       KillClientByFT(nc);
       exit;
     end;
-  finally
-    omsg.Free();
   end;
+  // send packet
+  ftransSendServerMsg(nc, trans_omsg);
 end;
 
 
@@ -757,11 +768,9 @@ var
   nc: ^TNetClient;
   nid: Integer = -1;
   msg: TMsg;
-  omsg: TMsg;
   cmd: Byte;
   tf: ^TNetFileTransfer;
   fname: string;
-  pkt: PENetPacket;
   chunk: Integer;
   ridx: Integer;
   dfn: AnsiString;
@@ -773,14 +782,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 +803,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 +831,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 +839,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);
@@ -863,28 +871,13 @@ begin
         tf.inProgress := False; // waiting for the first ACK or for the cancel
         GetMem(tf.diskBuffer, tf.chunkSize);
         // sent file info message
-        omsg.Alloc(NET_BUFSIZE);
-        try
-          omsg.Clear();
-          omsg.Write(Byte(NTF_SERVER_FILE_INFO));
-          omsg.Write(tf.hash);
-          omsg.Write(tf.size);
-          omsg.Write(tf.chunkSize);
-          omsg.Write(ExtractFileName(fname));
-          pkt := enet_packet_create(omsg.Data, omsg.CurSize, ENET_PACKET_FLAG_RELIABLE);
-          if not Assigned(pkt) then
-          begin
-            KillClientByFT(nc^);
-            exit;
-          end;
-          if (enet_peer_send(nc.Peer, NET_CHAN_DOWNLOAD_EX, pkt) <> 0) then
-          begin
-            KillClientByFT(nc^);
-            exit;
-          end;
-        finally
-          omsg.Free();
-        end;
+        trans_omsg.Clear();
+        trans_omsg.Write(Byte(NTF_SERVER_FILE_INFO));
+        trans_omsg.Write(tf.hash);
+        trans_omsg.Write(tf.size);
+        trans_omsg.Write(tf.chunkSize);
+        trans_omsg.Write(ExtractFileName(fname));
+        if not ftransSendServerMsg(nc^, trans_omsg) then exit;
       end;
     NTF_CLIENT_ABORT: // do not send requested file, or abort current transfer
       begin
@@ -926,6 +919,7 @@ begin
         tf.inProgress := True;
         tf.lastSentChunk := chunk-1;
         tf.lastAckChunk := chunk-1;
+        ProcessChunkSend(nc^);
       end;
     NTF_CLIENT_ACK: // chunk ack; chunk number follows
       begin
@@ -960,47 +954,41 @@ 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]);
+        ProcessChunkSend(nc^);
       end;
     NTF_CLIENT_MAP_REQUEST:
       begin
         e_LogWritefln('client #%d requested map info', [nc.ID]);
-        omsg.Alloc(NET_BUFSIZE);
-        try
-          omsg.Clear();
-          dfn := findDiskWad(MapsDir+gGameSettings.WAD);
-          if (dfn = '') then dfn := '!wad_not_found!.wad'; //FIXME
-          md5 := MD5File(dfn);
-          st := openDiskFileRO(dfn);
-          if not assigned(st) then exit; //wtf?!
-          size := st.size;
-          st.Free;
-          // packet type
-          omsg.Write(Byte(NTF_SERVER_MAP_INFO));
-          // map wad name
-          omsg.Write(gGameSettings.WAD);
-          // map wad md5
-          omsg.Write(md5);
-          // map wad size
-          omsg.Write(size);
-          // number of external resources for map
-          omsg.Write(LongInt(gExternalResources.Count));
-          // external resource names
-          for f := 0 to gExternalResources.Count-1 do
-          begin
-            omsg.Write(ExtractFileName(gExternalResources[f])); // GameDir+'/wads/'+ResList.Strings[i]
-          end;
-          // send packet
-          pkt := enet_packet_create(omsg.Data, omsg.CurSize, ENET_PACKET_FLAG_RELIABLE);
-          if not Assigned(pkt) then exit;
-          if (enet_peer_send(nc.Peer, NET_CHAN_DOWNLOAD_EX, pkt) <> 0) then exit;
-        finally
-          omsg.Free();
+        trans_omsg.Clear();
+        dfn := findDiskWad(MapsDir+gGameSettings.WAD);
+        if (dfn = '') then dfn := '!wad_not_found!.wad'; //FIXME
+        md5 := MD5File(dfn);
+        st := openDiskFileRO(dfn);
+        if not assigned(st) then exit; //wtf?!
+        size := st.size;
+        st.Free;
+        // packet type
+        trans_omsg.Write(Byte(NTF_SERVER_MAP_INFO));
+        // map wad name
+        trans_omsg.Write(gGameSettings.WAD);
+        // map wad md5
+        trans_omsg.Write(md5);
+        // map wad size
+        trans_omsg.Write(size);
+        // number of external resources for map
+        trans_omsg.Write(LongInt(gExternalResources.Count));
+        // external resource names
+        for f := 0 to gExternalResources.Count-1 do
+        begin
+          trans_omsg.Write(ExtractFileName(gExternalResources[f])); // GameDir+'/wads/'+ResList.Strings[i]
         end;
+        // send packet
+        if not ftransSendServerMsg(nc^, trans_omsg) then exit;
       end;
     else
       begin
-        KillClientByFT(NetClients[nid]);
+        KillClientByFT(nc^);
         exit;
       end;
   end;
@@ -1014,7 +1002,8 @@ var
   ID: Integer;
   TC: pTNetClient;
   TP: TPlayer;
-  f: Integer;
+  //f: Integer;
+  //ctt: Int64;
 begin
   IP := '';
   Result := 0;
@@ -1022,13 +1011,20 @@ 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
     if (not NetClients[f].Used) then continue;
     if (NetClients[f].Transfer.stream = nil) then continue;
-    ProcessHostFileTransfers(NetClients[f]);
+    ProcessChunkSend(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
@@ -1463,64 +1459,6 @@ begin
             e_KeyPressed(JOY3_JUMP)
 end;
 
-{
-function g_Net_Wait_Event(msgId: Word): TMemoryStream;
-  var
-    ev: ENetEvent;
-    rMsgId: Byte;
-    Ptr: Pointer;
-    stream: TMemoryStream;
-    status: cint;
-begin
-  FillChar(ev, SizeOf(ev), 0);
-  stream := nil;
-  repeat
-    status := enet_host_service(NetHost, @ev, Trunc(g_Net_DownloadTimeout * 1000));
-    if status > 0 then
-    begin
-      case ev.kind of
-        ENET_EVENT_TYPE_RECEIVE:
-          begin
-            Ptr := ev.packet^.data;
-            rMsgId := Byte(Ptr^);
-            if rMsgId = msgId then
-            begin
-              stream := TMemoryStream.Create;
-              stream.SetSize(ev.packet^.dataLength);
-              stream.WriteBuffer(Ptr^, ev.packet^.dataLength);
-              stream.Seek(0, soFromBeginning);
-              status := 1 (* received *)
-            end
-            else
-            begin
-              (* looks that game state always received, so ignore it *)
-              e_LogWritefln('g_Net_Wait_Event(%s): skip message %s', [msgId, rMsgId]);
-              status := 2 (* continue *)
-            end
-          end;
-      ENET_EVENT_TYPE_DISCONNECT:
-        begin
-          if (ev.data <= NET_DISC_MAX) then
-            g_Console_Add(_lc[I_NET_MSG_ERROR] + _lc[I_NET_ERR_CONN] + ' ' + _lc[TStrings_Locale(Cardinal(I_NET_DISC_NONE) + ev.data)], True);
-          status := -2 (* error: disconnected *)
-        end;
-      else
-        g_Console_Add(_lc[I_NET_MSG_ERROR] + _lc[I_NET_ERR_CONN] + ' unknown ENet event ' + IntToStr(Ord(ev.kind)), True);
-        status := -3 (* error: unknown event *)
-      end;
-      enet_packet_destroy(ev.packet)
-    end
-    else
-    begin
-      g_Console_Add(_lc[I_NET_MSG_ERROR] + _lc[I_NET_ERR_CONN] + ' timeout reached', True);
-      status := 0 (* error: timeout *)
-    end;
-    ProcessLoading(true);
-  until (status <> 2) or g_Net_UserRequestExit();
-  Result := stream
-end;
-}
-
 
 function getNewTimeoutEnd (): Int64;
 begin
@@ -1537,26 +1475,15 @@ end;
 
 
 function g_Net_SendMapRequest (): Boolean;
-var
-  msg: TMsg;
-  pkt: PENetPacket;
 begin
   result := false;
   e_LogWritefln('sending map request...', []);
   // send request
-  msg.Alloc(NET_BUFSIZE);
-  try
-    msg.Clear();
-    msg.Write(Byte(NTF_CLIENT_MAP_REQUEST));
-    e_LogWritefln('  request size is %d', [msg.CurSize]);
-    pkt := enet_packet_create(msg.Data, msg.CurSize, ENET_PACKET_FLAG_RELIABLE);
-    if not Assigned(pkt) then exit;
-    if (enet_peer_send(NetPeer, NET_CHAN_DOWNLOAD_EX, pkt) <> 0) then exit;
-    enet_host_flush(NetHost);
-  finally
-    msg.Free();
-  end;
-  result := true;
+  trans_omsg.Clear();
+  trans_omsg.Write(Byte(NTF_CLIENT_MAP_REQUEST));
+  e_LogWritefln('  request size is %d', [trans_omsg.CurSize]);
+  result := ftransSendClientMsg(trans_omsg);
+  if result then enet_host_flush(NetHost);
 end;
 
 
@@ -1618,7 +1545,7 @@ begin
                 //e_LogWritefln('g_Net_Wait_MapInfo: skip message from non-transfer channel', []);
                 freePacket := false;
                 g_Net_Client_HandlePacket(ev.packet, g_Net_ClientLightMsgHandler);
-                if (g_Res_received_map_start) then begin result := -666; exit; end;
+                if (g_Res_received_map_start < 0) then begin result := -666; exit; end;
               end
               else
               begin
@@ -1706,7 +1633,7 @@ begin
         end;
         if (freePacket) then begin freePacket := false; enet_packet_destroy(ev.packet); end;
       end;
-      ProcessLoading(true);
+      ProcessLoading();
       if g_Net_UserRequestExit() then
       begin
         g_Console_Add(_lc[I_NET_MSG_ERROR] + _lc[I_NET_ERR_CONN] + ' user abort', True);
@@ -1741,28 +1668,12 @@ var
   freePacket: Boolean = false;
   ct, ett: Int64;
   status: cint;
-  pkt: PENetPacket;
 begin
   // send request
-  msg.Alloc(NET_BUFSIZE);
-  try
-    msg.Clear();
-    msg.Write(Byte(NTF_CLIENT_FILE_REQUEST));
-    msg.Write(resIndex);
-    pkt := enet_packet_create(msg.Data, msg.CurSize, ENET_PACKET_FLAG_RELIABLE);
-    if not Assigned(pkt) then
-    begin
-      result := -1;
-      exit;
-    end;
-    if (enet_peer_send(NetPeer, NET_CHAN_DOWNLOAD_EX, pkt) <> 0) then
-    begin
-      result := -1;
-      exit;
-    end;
-  finally
-    msg.Free();
-  end;
+  trans_omsg.Clear();
+  trans_omsg.Write(Byte(NTF_CLIENT_FILE_REQUEST));
+  trans_omsg.Write(resIndex);
+  if not ftransSendClientMsg(trans_omsg) then begin result := -1; exit; end;
 
   FillChar(ev, SizeOf(ev), 0);
   Result := -1;
@@ -1799,7 +1710,7 @@ begin
                 //e_LogWriteln('g_Net_Wait_Event: skip message from non-transfer channel');
                 freePacket := false;
                 g_Net_Client_HandlePacket(ev.packet, g_Net_ClientLightMsgHandler);
-                if (g_Res_received_map_start) then begin result := -666; exit; end;
+                if (g_Res_received_map_start < 0) then begin result := -666; exit; end;
               end
               else
               begin
@@ -1866,7 +1777,7 @@ begin
         end;
         if (freePacket) then begin freePacket := false; enet_packet_destroy(ev.packet); end;
       end;
-      ProcessLoading(true);
+      ProcessLoading();
       if g_Net_UserRequestExit() then
       begin
         g_Console_Add(_lc[I_NET_MSG_ERROR] + _lc[I_NET_ERR_CONN] + ' user abort', True);
@@ -1881,25 +1792,14 @@ end;
 
 
 function g_Net_AbortResTransfer (var tf: TNetFileTransfer): Boolean;
-var
-  msg: TMsg;
-  pkt: PENetPacket;
 begin
   result := false;
   e_LogWritefln('aborting file transfer...', []);
   // send request
-  msg.Alloc(NET_BUFSIZE);
-  try
-    msg.Clear();
-    msg.Write(Byte(NTF_CLIENT_ABORT));
-    pkt := enet_packet_create(msg.Data, msg.CurSize, ENET_PACKET_FLAG_RELIABLE);
-    if not Assigned(pkt) then exit;
-    if (enet_peer_send(NetPeer, NET_CHAN_DOWNLOAD_EX, pkt) <> 0) then exit;
-    enet_host_flush(NetHost);
-  finally
-    msg.Free();
-  end;
-  result := true;
+  trans_omsg.Clear();
+  trans_omsg.Write(Byte(NTF_CLIENT_ABORT));
+  result := ftransSendClientMsg(trans_omsg);
+  if result then enet_host_flush(NetHost);
 end;
 
 
@@ -1920,28 +1820,36 @@ var
   rMsgId: Byte;
   Ptr: Pointer;
   msg: TMsg;
-  omsg: TMsg;
   freePacket: Boolean = false;
   ct, ett: Int64;
   status: cint;
   nextChunk: Integer = 0;
+  chunkTotal: Integer;
   chunk: Integer;
   csize: Integer;
   buf: PChar = nil;
-  pkt: PENetPacket;
+  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
-  msg.Alloc(NET_BUFSIZE);
-  try
-    msg.Clear();
-    msg.Write(Byte(NTF_CLIENT_START));
-    msg.Write(LongInt(0));
-    pkt := enet_packet_create(msg.Data, msg.CurSize, ENET_PACKET_FLAG_RELIABLE);
-    if not Assigned(pkt) then exit;
-    if (enet_peer_send(NetPeer, NET_CHAN_DOWNLOAD_EX, pkt) <> 0) then exit;
-  finally
-    msg.Free();
-  end;
+  trans_omsg.Clear();
+  trans_omsg.Write(Byte(NTF_CLIENT_START));
+  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);
@@ -1950,6 +1858,7 @@ begin
   try
     ett := getNewTimeoutEnd();
     repeat
+      //stx := -GetTimerMS();
       status := enet_host_service(NetHost, @ev, 300);
       if (status < 0) then
       begin
@@ -1980,10 +1889,13 @@ begin
                 //e_LogWritefln('g_Net_Wait_Event: skip message from non-transfer channel', []);
                 freePacket := false;
                 g_Net_Client_HandlePacket(ev.packet, g_Net_ClientLightMsgHandler);
-                if (g_Res_received_map_start) then begin result := -666; exit; end;
+                if (g_Res_received_map_start < 0) then begin result := -666; exit; end;
               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,22 +1928,16 @@ 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
-                    omsg.Clear();
-                    omsg.Write(Byte(NTF_CLIENT_ACK));
-                    omsg.Write(LongInt(chunk));
-                    pkt := enet_packet_create(omsg.Data, omsg.CurSize, ENET_PACKET_FLAG_RELIABLE);
-                    if not Assigned(pkt) then exit;
-                    if (enet_peer_send(NetPeer, NET_CHAN_DOWNLOAD_EX, pkt) <> 0) then exit;
-                  finally
-                    omsg.Free();
-                  end;
+                  trans_omsg.Clear();
+                  trans_omsg.Write(Byte(NTF_CLIENT_ACK));
+                  trans_omsg.Write(LongInt(chunk));
+                  if not ftransSendClientMsg(trans_omsg) then begin result := -1; exit; end;
                 end
                 else if (rMsgId = NTF_SERVER_ABORT) then
                 begin
@@ -2045,6 +1951,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:
@@ -2063,7 +1971,7 @@ begin
         end;
         if (freePacket) then begin freePacket := false; enet_packet_destroy(ev.packet); end;
       end;
-      ProcessLoading(true);
+      ProcessLoading();
       if g_Net_UserRequestExit() then
       begin
         g_Console_Add(_lc[I_NET_MSG_ERROR] + _lc[I_NET_ERR_CONN] + ' user abort', True);
@@ -2349,6 +2257,7 @@ initialization
   NetOut.Alloc(NET_BUFSIZE);
   NetBuf[NET_UNRELIABLE].Alloc(NET_BUFSIZE*2);
   NetBuf[NET_RELIABLE].Alloc(NET_BUFSIZE*2);
+  trans_omsg.Alloc(NET_BUFSIZE);
 finalization
   NetIn.Free();
   NetOut.Free();