DEADSOFTWARE

Net: Don't process network in ProcessLoading() for client's code
authorDmitry D. Chernov <blackdoomer@yandex.ru>
Mon, 13 Mar 2023 21:43:46 +0000 (07:43 +1000)
committerDmitry D. Chernov <blackdoomer@yandex.ru>
Mon, 13 Mar 2023 21:50:18 +0000 (07:50 +1000)
This should fix freezing problems with downloading maps and their resources from the server:
https://doom2d.org/forum/viewtopic.php?f=36&t=2366
Also performed a bit of cosmetics and unmuted some warnings.

src/game/g_game.pas
src/game/g_net.pas
src/game/g_nethandler.pas
src/game/g_res_downloader.pas
src/game/g_window.pas

index 261d5e9fe19c34c3fc46c193c917ba7b7cee43ce..b1a10ea8ba434ccaf0394d86b186678309e2ffaa 100644 (file)
@@ -4854,12 +4854,6 @@ begin
     begin
       if (NetEvent.kind = ENET_EVENT_TYPE_RECEIVE) then
       begin
-        if (NetEvent.channelID = NET_CHAN_DOWNLOAD_EX) then
-        begin
-          // ignore all download packets, they're processed by separate code
-          enet_packet_destroy(NetEvent.packet);
-          continue;
-        end;
         Ptr := NetEvent.packet^.data;
         if not InMsg.Init(Ptr, NetEvent.packet^.dataLength, True) then
         begin
@@ -4959,8 +4953,7 @@ begin
       end;
     end;
 
-    ProcessLoading(true);
-
+    ProcessLoading(True);
     if g_Net_UserRequestExit() then
     begin
       State := 0;
@@ -8308,8 +8301,7 @@ begin
   end;
 
   g_ActiveWindow := nil;
-
-  ProcessLoading(true);
+  ProcessLoading(True);
 end;
 
 procedure g_Game_StepLoading(Value: Integer = -1);
@@ -8323,10 +8315,11 @@ begin
     end
     else
       CurValue := Value;
+
     if (ShowCount > LOADING_SHOW_STEP) or (Value > -1) then
     begin
       ShowCount := 0;
-      ProcessLoading();
+      ProcessLoading(False);
     end;
   end;
 end;
index 3a233da20e47efe7d962b5fb489041afebddda5d..6a17f7e52be79bf63cea6a249a27b940f5c5b822 100644 (file)
@@ -214,7 +214,6 @@ function  g_Net_Connect(IP: string; Port: enet_uint16): Boolean;
 procedure g_Net_Disconnect(Forced: Boolean = False);
 procedure g_Net_Client_Send(Reliable: Boolean; Chan: Byte = NET_CHAN_GAME);
 procedure g_Net_Client_Update();
-procedure g_Net_Client_UpdateWhileLoading();
 
 function  g_Net_Client_ByName(Name: string): pTNetClient;
 function  g_Net_Client_ByPlayer(PID: Word): pTNetClient;
@@ -920,7 +919,8 @@ begin
         end;
         if (freePacket) then begin freePacket := false; enet_packet_destroy(ev.packet); end;
       end;
-      ProcessLoading();
+
+      ProcessLoading(False);
       if g_Net_UserRequestExit() then
       begin
         g_Console_Add(_lc[I_NET_MSG_ERROR] + _lc[I_NET_ERR_CONN] + ' user abort', True);
@@ -1068,7 +1068,8 @@ begin
         end;
         if (freePacket) then begin freePacket := false; enet_packet_destroy(ev.packet); end;
       end;
-      ProcessLoading();
+
+      ProcessLoading(False);
       if g_Net_UserRequestExit() then
       begin
         g_Console_Add(_lc[I_NET_MSG_ERROR] + _lc[I_NET_ERR_CONN] + ' user abort', True);
@@ -1267,7 +1268,8 @@ begin
         end;
         if (freePacket) then begin freePacket := false; enet_packet_destroy(ev.packet); end;
       end;
-      ProcessLoading();
+
+      ProcessLoading(False);
       if g_Net_UserRequestExit() then
       begin
         g_Console_Add(_lc[I_NET_MSG_ERROR] + _lc[I_NET_ERR_CONN] + ' user abort', True);
@@ -1949,7 +1951,6 @@ begin
     case NetEvent.kind of
       ENET_EVENT_TYPE_RECEIVE:
       begin
-        if (NetEvent.channelID = NET_CHAN_DOWNLOAD_EX) then continue; // ignore all download packets, they're processed by separate code
         if NetDump then g_Net_DumpRecvBuffer(NetEvent.packet^.data, NetEvent.packet^.dataLength);
         g_Net_Client_HandlePacket(NetEvent.packet, g_Net_ClientMsgHandler);
       end;
@@ -1963,28 +1964,6 @@ begin
   end
 end;
 
-procedure g_Net_Client_UpdateWhileLoading();
-begin
-  while (enet_host_service(NetHost, @NetEvent, 0) > 0) do
-  begin
-    case NetEvent.kind of
-      ENET_EVENT_TYPE_RECEIVE:
-      begin
-        if (NetEvent.channelID = NET_CHAN_DOWNLOAD_EX) then continue; // ignore all download packets, they're processed by separate code
-        if NetDump then g_Net_DumpRecvBuffer(NetEvent.packet^.data, NetEvent.packet^.dataLength);
-        g_Net_Client_HandlePacket(NetEvent.packet, g_Net_ClientLightMsgHandler);
-      end;
-
-      ENET_EVENT_TYPE_DISCONNECT:
-      begin
-        g_Net_Disconnect(True);
-        Exit;
-      end;
-    end;
-  end;
-  g_Net_Flush();
-end;
-
 function g_Net_Connect(IP: string; Port: enet_uint16): Boolean;
 var
   OuterLoop: Boolean;
@@ -2067,8 +2046,7 @@ begin
       g_Console_Add(Format(_lc[I_NET_MSG_PORTS], [Integer(Port), Integer(NET_PING_PORT)]), True);
     end;
 
-    ProcessLoading(true);
-
+    ProcessLoading(True);
     if e_KeyPressed(IK_SPACE) or e_KeyPressed(IK_ESCAPE) or e_KeyPressed(VK_ESCAPE) or
        e_KeyPressed(JOY0_JUMP) or e_KeyPressed(JOY1_JUMP) or e_KeyPressed(JOY2_JUMP) or e_KeyPressed(JOY3_JUMP) then
       OuterLoop := False;
@@ -2164,23 +2142,16 @@ var
 begin
   dataLength := Length(Data);
 
-  if (Reliable) then
-    F := LongWord(ENET_PACKET_FLAG_RELIABLE)
-  else
-    F := 0;
+  if Reliable
+    then F := LongWord(ENET_PACKET_FLAG_RELIABLE)
+    else F := 0;
 
-  if (peer <> nil) then
-  begin
-    P := enet_packet_create(@Data[0], dataLength, F);
-    if not Assigned(P) then Exit;
-    enet_peer_send(peer, Chan, P);
-  end
-  else
-  begin
-    P := enet_packet_create(@Data[0], dataLength, F);
-    if not Assigned(P) then Exit;
-    enet_host_broadcast(NetHost, Chan, P);
-  end;
+  P := enet_packet_create(@Data[0], dataLength, F);
+  if not Assigned(P) then exit;
+
+  if peer <> nil
+    then enet_peer_send(peer, Chan, P)
+    else enet_host_broadcast(NetHost, Chan, P);
 
   enet_host_flush(NetHost);
 end;
index 4dc52a395c6152a05cd3c8cbc2581831b1ead811..ccaddfc87b2b29e1d2966f78d080aa30db6f7ed1 100644 (file)
@@ -34,6 +34,7 @@ implementation
 
 uses sysutils, g_console;
 
+// TODO: Unify this with g_Net_Host_HandlePacket() somehow? They're almost the same.
 procedure g_Net_Client_HandlePacket(P: pENetPacket; Handler: TNetClientMsgHandler);
 var
   MNext: Integer;
@@ -42,8 +43,8 @@ var
   NetMsg: TMsg;
   Err: Boolean;
 begin
-  if not NetMsg.Init(P^.data, P^.dataLength, True) then
-    Exit;
+  if not NetMsg.Init(P^.data, P^.dataLength, True)
+    then exit;
 
   Err := False;
   MNext := 0;
@@ -60,10 +61,9 @@ begin
     end;
   end;
 
-  MHandled := not MHandled; //k8: stfu, fpc!
-
   enet_packet_destroy(P);
-  //if Err then begin MC_MalformedPacket(S); Exit; end;
+  //if Err
+  //  then MC_MalformedPacket(S);
 end;
 
 procedure g_Net_Host_HandlePacket(S: pTNetClient; P: pENetPacket; Handler: TNetHostMsgHandler);
@@ -74,8 +74,8 @@ var
   NetMsg: TMsg;
   Err: Boolean;
 begin
-  if not NetMsg.Init(P^.data, P^.dataLength, True) then
-    Exit;
+  if not NetMsg.Init(P^.data, P^.dataLength, True)
+    then exit;
 
   Err := False;
   MNext := 0;
@@ -92,10 +92,9 @@ begin
     end;
   end;
 
-  MHandled := not MHandled; //k8: stfu, fpc!
-
   enet_packet_destroy(P);
-  if Err then begin MH_MalformedPacket(S); Exit; end;
+  if Err
+    then MH_MalformedPacket(S);
 end;
 
 
index 7fc295119c4cdada4b8e7b98f8db5fb2026f6f6e..73557a590a4c39b6655de16d64a4352c077cb77c 100644 (file)
@@ -374,7 +374,7 @@ begin
   sfsGCCollect(); // why not?
   g_Res_CreateDatabases();
   FileName := ExtractFileName(FileName);
-  if (length(FileName) = 0) then FileName := '__unititled__.wad';
+  if (length(FileName) = 0) then FileName := '__untitled__.wad';
 
   try
     g_Res_received_map_start := 1;
index 37d979111dff1a34f01f50f30a3287c77f901493..d3850c8e666e10422bfc13eeeb1a587be1c76b0c 100644 (file)
@@ -22,7 +22,7 @@ uses
 
 function SDLMain (): Integer;
 procedure ResetTimer ();
-procedure ProcessLoading (forceUpdate: Boolean=false);
+procedure ProcessLoading (forceUpdate: Boolean = False);
 
 var
   gwin_dump_extensions: Boolean = false;
@@ -68,7 +68,7 @@ var
   prevLoadingUpdateTime: UInt64 = 0;
 {$ENDIF}
 
-procedure ProcessLoading (forceUpdate: Boolean=false);
+procedure ProcessLoading (forceUpdate: Boolean);
 {$IFNDEF HEADLESS}
 var
   stt: UInt64;
@@ -108,14 +108,13 @@ begin
 
   e_SoundUpdate();
 
-  if NetMode = NET_SERVER then
-  begin
-    g_Net_Host_Update();
-  end
-  else
-  begin
-    if (NetMode = NET_CLIENT) and (NetState <> NET_STATE_AUTH) then g_Net_Client_UpdateWhileLoading();
-  end;
+  // TODO: At the moment, I left here only host network processing, because the client code must
+  // handle network events on its own. Otherwise separate network cases that use different calls to
+  // enet_host_service() WILL lose their packets (for example, resource downloading). So they have
+  // to handle everything by themselves. But in general, this MUST be removed completely, since
+  // updating the window should never affect the network. Use single enet_host_service(), period.
+  if NetMode = NET_SERVER
+    then g_Net_Host_Update();
 end;