DEADSOFTWARE

Cosmetic: DooM 2D:Forever -> Doom 2D: Forever
[d2df-sdl.git] / src / game / g_net.pas
index b8f957a32cfb32840360e0382db804f931611506..cbf5120782839a5703caa116a5d0041465411410 100644 (file)
@@ -1,13 +1,28 @@
-{$MODE DELPHI}
+(* Copyright (C)  Doom 2D: Forever Developers
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *)
+{$INCLUDE ../shared/a_modes.inc}
 unit g_net;
 
 interface
 
 uses
-  e_log, e_fixedbuffer, ENet, ENetTypes, ENetPlatform, Classes;
+  e_log, e_msg, ENet, Classes, MAPDEF;
 
 const
-  NET_PROTOCOL_VER = 165;
+  NET_PROTOCOL_VER = 173;
 
   NET_MAXCLIENTS = 24;
   NET_CHANS = 11;
@@ -28,7 +43,7 @@ const
   NET_SERVER = 1;
   NET_CLIENT = 2;
 
-  NET_BUFSIZE = 65536;
+  NET_BUFSIZE = $FFFF;
 
   NET_EVERYONE = -1;
 
@@ -48,6 +63,7 @@ const
   NET_STATE_GAME = 2;
 
   BANLIST_FILENAME = 'banlist.txt';
+  NETDUMP_FILENAME = 'netdump';
 
 type
   TNetClient = record
@@ -71,6 +87,7 @@ type
 var
   NetInitDone:     Boolean = False;
   NetMode:         Byte = NET_NONE;
+  NetDump:         Boolean = False;
 
   NetServerName:   string = 'Unnamed Server';
   NetPassword:     string = '';
@@ -99,7 +116,7 @@ var
   NetClientIP:   string = '127.0.0.1';
   NetClientPort: Word   = 25666;
 
-  NetIn, NetOut: TBuffer;
+  NetIn, NetOut: TMsg;
 
   NetClients:     array of TNetClient;
   NetClientCount: Byte = 0;
@@ -123,6 +140,8 @@ var
 
   NetGotEverything: Boolean = False;
 
+  NetDumpFile: TStream;
+
 function  g_Net_Init(): Boolean;
 procedure g_Net_Cleanup();
 procedure g_Net_Free();
@@ -157,12 +176,17 @@ function  g_Net_UnbanHost(IP: LongWord): Boolean; overload;
 procedure g_Net_UnbanNonPermHosts();
 procedure g_Net_SaveBanList();
 
+procedure g_Net_DumpStart();
+procedure g_Net_DumpSendBuffer();
+procedure g_Net_DumpRecvBuffer(Buf: penet_uint8; Len: LongWord);
+procedure g_Net_DumpEnd();
+
 implementation
 
 uses
   SysUtils,
   e_input, g_nethandler, g_netmsg, g_netmaster, g_player, g_window, g_console,
-  g_main, g_game, g_language, g_weapons;
+  g_main, g_game, g_language, g_weapons, utils;
 
 
 { /// SERVICE FUNCTIONS /// }
@@ -224,8 +248,8 @@ var
   IPstr: string;
   IP: LongWord;
 begin
-  e_Buffer_Clear(@NetIn);
-  e_Buffer_Clear(@NetOut);
+  NetIn.Clear();
+  NetOut.Clear();
   SetLength(NetClients, 0);
   NetPeer := nil;
   NetHost := nil;
@@ -258,8 +282,8 @@ end;
 
 procedure g_Net_Cleanup();
 begin
-  e_Buffer_Clear(@NetIn);
-  e_Buffer_Clear(@NetOut);
+  NetIn.Clear();
+  NetOut.Clear();
 
   SetLength(NetClients, 0);
   NetClientCount := 0;
@@ -280,6 +304,9 @@ begin
   NetTimeToReliable := 0;
 
   NetMode := NET_NONE;
+
+  if NetDump then
+    g_Net_DumpEnd();
 end;
 
 procedure g_Net_Free();
@@ -346,7 +373,10 @@ begin
   end;
 
   NetMode := NET_SERVER;
-  e_Buffer_Clear(@NetOut);
+  NetOut.Clear();
+
+  if NetDump then
+    g_Net_DumpStart();
 end;
 
 procedure g_Net_Host_Die();
@@ -384,7 +414,7 @@ begin
   NetMode := NET_NONE;
 
   g_Net_Cleanup;
-  e_WriteLog('NET: Server stopped', MSG_NOTIFY);
+  e_WriteLog('NET: Server stopped', TMsgType.Notify);
 end;
 
 
@@ -403,21 +433,22 @@ begin
     if ID > High(NetClients) then Exit;
     if NetClients[ID].Peer = nil then Exit;
 
-    P := enet_packet_create(Addr(NetOut.Data), NetOut.Len, F);
+    P := enet_packet_create(NetOut.Data, NetOut.CurSize, F);
     if not Assigned(P) then Exit;
 
     enet_peer_send(NetClients[ID].Peer, Chan, P);
   end
   else
   begin
-    P := enet_packet_create(Addr(NetOut.Data), NetOut.Len, F);
+    P := enet_packet_create(NetOut.Data, NetOut.CurSize, F);
     if not Assigned(P) then Exit;
 
-    enet_host_widecast(NetHost, Chan, P);
+    enet_host_broadcast(NetHost, Chan, P);
   end;
 
+  if NetDump then g_Net_DumpSendBuffer();
   g_Net_Flush();
-  e_Buffer_Clear(@NetOut);
+  NetOut.Clear();
 end;
 
 procedure g_Net_Host_CheckPings();
@@ -443,22 +474,22 @@ begin
   begin
     ClTime := Int64(Addr(Ping[2])^);
 
-    e_Buffer_Clear(@NetOut);
-    e_Buffer_Write(@NetOut, Byte(Ord('D')));
-    e_Buffer_Write(@NetOut, Byte(Ord('F')));
-    e_Buffer_Write(@NetOut, ClTime);
+    NetOut.Clear();
+    NetOut.Write(Byte(Ord('D')));
+    NetOut.Write(Byte(Ord('F')));
+    NetOut.Write(ClTime);
     g_Net_Slist_WriteInfo();
     NPl := 0;
     if gPlayer1 <> nil then Inc(NPl);
     if gPlayer2 <> nil then Inc(NPl);
-    e_Buffer_Write(@NetOut, NPl);
-    e_Buffer_Write(@NetOut, gNumBots);
+    NetOut.Write(NPl);
+    NetOut.Write(gNumBots);
 
-    Buf.data := Addr(NetOut.Data[0]);
-    Buf.dataLength := NetOut.WritePos;
+    Buf.data := NetOut.Data;
+    Buf.dataLength := NetOut.CurSize;
     enet_socket_send(NetPongSock, @ClAddr, @Buf, 1);
 
-    e_Buffer_Clear(@NetOut);
+    NetOut.Clear();
   end;
 end;
 
@@ -531,6 +562,7 @@ begin
         if ID > High(NetClients) then Exit;
         TC := @NetClients[ID];
 
+        if NetDump then g_Net_DumpRecvBuffer(NetEvent.packet^.data, NetEvent.packet^.dataLength);
         g_Net_HostMsgHandler(TC, NetEvent.packet);
       end;
 
@@ -550,7 +582,7 @@ begin
           TP.Lives := 0;
           TP.Kill(K_SIMPLEKILL, 0, HIT_DISCON);
           g_Console_Add(Format(_lc[I_PLAYER_LEAVE], [TP.Name]), True);
-          e_WriteLog('NET: Client ' + TP.Name + ' [' + IntToStr(ID) + '] disconnected.', MSG_NOTIFY);
+          e_WriteLog('NET: Client ' + TP.Name + ' [' + IntToStr(ID) + '] disconnected.', TMsgType.Notify);
           g_Player_Remove(TP.UID);
         end;
 
@@ -604,7 +636,7 @@ begin
   end
   else
   begin
-    e_WriteLog('NET: Kicked from server: ' + IntToStr(NetEvent.data), MSG_NOTIFY);
+    e_WriteLog('NET: Kicked from server: ' + IntToStr(NetEvent.data), TMsgType.Notify);
     if (NetEvent.data <= NET_DISC_MAX) then
       g_Console_Add(_lc[I_NET_MSG] + _lc[I_NET_MSG_KICK] +
         _lc[TStrings_Locale(Cardinal(I_NET_DISC_NONE) + NetEvent.data)], True);
@@ -618,7 +650,7 @@ begin
   g_Console_Add(_lc[I_NET_MSG] + _lc[I_NET_MSG_CLIENT_DISC]);
 
   g_Net_Cleanup;
-  e_WriteLog('NET: Disconnected', MSG_NOTIFY);
+  e_WriteLog('NET: Disconnected', TMsgType.Notify);
 end;
 
 procedure g_Net_Client_Send(Reliable: Boolean; Chan: Byte = NET_CHAN_GAME);
@@ -631,12 +663,13 @@ begin
   else
     F := 0;
 
-  P := enet_packet_create(Addr(NetOut.Data), NetOut.Len, F);
+  P := enet_packet_create(NetOut.Data, NetOut.CurSize, F);
   if not Assigned(P) then Exit;
 
   enet_peer_send(NetPeer, Chan, P);
+  if NetDump then g_Net_DumpSendBuffer();
   g_Net_Flush();
-  e_Buffer_Clear(@NetOut);
+  NetOut.Clear();
 end;
 
 function g_Net_Client_Update(): enet_size_t;
@@ -646,7 +679,10 @@ begin
   begin
     case NetEvent.kind of
       ENET_EVENT_TYPE_RECEIVE:
+      begin
+        if NetDump then g_Net_DumpRecvBuffer(NetEvent.packet^.data, NetEvent.packet^.dataLength);
         g_Net_ClientMsgHandler(NetEvent.packet);
+      end;
 
       ENET_EVENT_TYPE_DISCONNECT:
       begin
@@ -665,7 +701,10 @@ begin
   begin
     case NetEvent.kind of
       ENET_EVENT_TYPE_RECEIVE:
+      begin
+        if NetDump then g_Net_DumpRecvBuffer(NetEvent.packet^.data, NetEvent.packet^.dataLength);
         g_Net_ClientLightMsgHandler(NetEvent.packet);
+      end;
 
       ENET_EVENT_TYPE_DISCONNECT:
       begin
@@ -738,17 +777,17 @@ begin
       begin
         g_Console_Add(_lc[I_NET_MSG] + _lc[I_NET_MSG_CLIENT_DONE]);
         NetMode := NET_CLIENT;
-        e_Buffer_Clear(@NetOut);
+        NetOut.Clear();
         enet_peer_timeout(NetPeer, ENET_PEER_TIMEOUT_LIMIT * 2, ENET_PEER_TIMEOUT_MINIMUM * 2, ENET_PEER_TIMEOUT_MAXIMUM * 2);
         NetClientIP := IP;
         NetClientPort := Port;
+        if NetDump then
+          g_Net_DumpStart();
         Exit;
       end;
     end;
 
-    ProcessLoading();
-
-    e_PollInput();
+    ProcessLoading(true);
 
     if e_KeyPressed(IK_ESCAPE) or e_KeyPressed(IK_SPACE) then
       OuterLoop := False;
@@ -769,15 +808,11 @@ function IpToStr(IP: LongWord): string;
 var
   Ptr: Pointer;
 begin
-  Result := '';
   Ptr := Addr(IP);
-
-  e_Raw_Seek(0);
-  Result := Result + IntToStr(e_Raw_Read_Byte(Ptr)) + '.';
-  Result := Result + IntToStr(e_Raw_Read_Byte(Ptr)) + '.';
-  Result := Result + IntToStr(e_Raw_Read_Byte(Ptr)) + '.';
-  Result := Result + IntToStr(e_Raw_Read_Byte(Ptr));
-  e_Raw_Seek(0);
+  Result :=          IntToStr(PByte(Ptr + 0)^) + '.';
+  Result := Result + IntToStr(PByte(Ptr + 1)^) + '.';
+  Result := Result + IntToStr(PByte(Ptr + 2)^) + '.';
+  Result := Result + IntToStr(PByte(Ptr + 3)^);
 end;
 
 function StrToIp(IPstr: string; var IP: LongWord): Boolean;
@@ -862,7 +897,7 @@ begin
   begin
     P := enet_packet_create(@Data[0], dataLength, F);
     if not Assigned(P) then Exit;
-    enet_host_widecast(NetHost, Chan, P);
+    enet_host_broadcast(NetHost, Chan, P);
   end;
 
   enet_host_flush(NetHost);
@@ -915,9 +950,7 @@ begin
         end;
     end;
 
-    ProcessLoading();
-
-    e_PollInput();
+    ProcessLoading(true);
 
     if e_KeyPressed(IK_ESCAPE) or e_KeyPressed(IK_SPACE) then
       break;
@@ -1033,4 +1066,45 @@ begin
   CloseFile(F);
 end;
 
+procedure g_Net_DumpStart();
+begin
+  if NetMode = NET_SERVER then
+    NetDumpFile := createDiskFile(NETDUMP_FILENAME + '_server')
+  else
+    NetDumpFile := createDiskFile(NETDUMP_FILENAME + '_client');
+end;
+
+procedure g_Net_DumpSendBuffer();
+begin
+  writeInt(NetDumpFile, gTime);
+  writeInt(NetDumpFile, LongWord(NetOut.CurSize));
+  writeInt(NetDumpFile, Byte(1));
+  NetDumpFile.WriteBuffer(NetOut.Data^, NetOut.CurSize);
+end;
+
+procedure g_Net_DumpRecvBuffer(Buf: penet_uint8; Len: LongWord);
+begin
+  if (Buf = nil) or (Len = 0) then Exit;
+  writeInt(NetDumpFile, gTime);
+  writeInt(NetDumpFile, Len);
+  writeInt(NetDumpFile, Byte(0));
+  NetDumpFile.WriteBuffer(Buf^, Len);
+end;
+
+procedure g_Net_DumpEnd();
+begin
+  NetDumpFile.Free();
+  NetDumpFile := nil;
+end;
+
+initialization
+
+  NetIn.Alloc(NET_BUFSIZE);
+  NetOut.Alloc(NET_BUFSIZE);
+
+finalization
+
+  NetIn.Free();
+  NetOut.Free();
+
 end.