X-Git-Url: https://deadsoftware.ru/gitweb?a=blobdiff_plain;f=src%2Fgame%2Fg_net.pas;h=85263e51e7e709388809188f5c664c832f9f84e3;hb=f924968c450e1dc566b3abdde8d2aeac4de11fd0;hp=8738aa24001a67560546c69f05c9da819462d243;hpb=463a767a09beda018ae987a03628bfb93a847bbb;p=d2df-sdl.git diff --git a/src/game/g_net.pas b/src/game/g_net.pas index 8738aa2..85263e5 100644 --- a/src/game/g_net.pas +++ b/src/game/g_net.pas @@ -13,16 +13,16 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . *) -{$MODE DELPHI} +{$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 = 168; + NET_PROTOCOL_VER = 173; NET_MAXCLIENTS = 24; NET_CHANS = 11; @@ -43,7 +43,7 @@ const NET_SERVER = 1; NET_CLIENT = 2; - NET_BUFSIZE = 65536; + NET_BUFSIZE = $FFFF; NET_EVERYONE = -1; @@ -63,6 +63,7 @@ const NET_STATE_GAME = 2; BANLIST_FILENAME = 'banlist.txt'; + NETDUMP_FILENAME = 'netdump'; type TNetClient = record @@ -86,6 +87,7 @@ type var NetInitDone: Boolean = False; NetMode: Byte = NET_NONE; + NetDump: Boolean = False; NetServerName: string = 'Unnamed Server'; NetPassword: string = ''; @@ -114,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; @@ -138,6 +140,8 @@ var NetGotEverything: Boolean = False; + NetDumpFile: TStream; + function g_Net_Init(): Boolean; procedure g_Net_Cleanup(); procedure g_Net_Free(); @@ -172,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 /// } @@ -239,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; @@ -273,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; @@ -295,6 +304,9 @@ begin NetTimeToReliable := 0; NetMode := NET_NONE; + + if NetDump then + g_Net_DumpEnd(); end; procedure g_Net_Free(); @@ -361,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(); @@ -399,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; @@ -418,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(); @@ -458,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; @@ -546,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; @@ -565,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; @@ -619,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); @@ -633,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); @@ -646,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; @@ -661,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 @@ -680,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 @@ -753,15 +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(); + ProcessLoading(true); e_PollInput(); @@ -784,15 +810,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; @@ -877,7 +899,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); @@ -930,7 +952,7 @@ begin end; end; - ProcessLoading(); + ProcessLoading(true); e_PollInput(); @@ -1048,4 +1070,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.