From: fgsfds Date: Wed, 16 Aug 2017 17:44:19 +0000 (+0300) Subject: buffer network messages (broke a lot of shit) X-Git-Url: http://deadsoftware.ru/gitweb?a=commitdiff_plain;h=94c8854f0ba3a87de3928f587e66d5d0e43d8f9b;p=d2df-sdl.git buffer network messages (broke a lot of shit) --- diff --git a/src/engine/e_fixedbuffer.pas b/src/engine/e_fixedbuffer.pas index c593021..3b6dbf8 100644 --- a/src/engine/e_fixedbuffer.pas +++ b/src/engine/e_fixedbuffer.pas @@ -28,7 +28,7 @@ type Data: array [0..BUF_SIZE] of Byte; // îäèí áàéò ñâåðõó íà âñÿêèé ñëó÷àé ReadPos: Cardinal; WritePos: Cardinal; - Len: Cardinal; + Cap: Cardinal; end; pTBuffer = ^TBuffer; @@ -57,6 +57,8 @@ procedure e_Buffer_Write(B: pTBuffer; V: string); overload; procedure e_Buffer_Write(B: pTBuffer; V: TMD5Digest); overload; +procedure e_Buffer_Write(B: pTBuffer; V: pTBuffer); overload; + function e_Buffer_Read_Char(B: pTBuffer): Char; @@ -100,15 +102,15 @@ procedure e_Buffer_Clear(B: pTBuffer); begin B^.WritePos := 0; B^.ReadPos := 0; - B^.Len := 0; + B^.Cap := 0; end; procedure e_Buffer_Write_Generic(B: pTBuffer; var V; N: Cardinal); begin if (B^.WritePos + N >= BUF_SIZE) then Exit; - if (B^.WritePos + N > B^.Len) then - B^.Len := B^.WritePos + N + 1; + if (B^.WritePos + N > B^.Cap) then + B^.Cap := B^.WritePos + N + 1; CopyMemory(Pointer(NativeUInt(Addr(B^.Data)) + B^.WritePos), @V, N); @@ -177,7 +179,7 @@ begin P := BUF_SIZE; end; - if (P > B^.Len) then B^.Len := P; + if (P > B^.Cap) then B^.Cap := P; CopyMemory(Pointer(NativeUInt(Addr(B^.Data)) + B^.WritePos), @V[1], Len); @@ -193,6 +195,25 @@ begin e_Buffer_Write(B, V[I]); end; +procedure e_Buffer_Write(B: pTBuffer; V: pTBuffer); overload; +var + N: Cardinal; +begin + if V = nil then Exit; + N := V^.WritePos; + + e_Buffer_Write(B, Word(N)); + + if (B^.WritePos + N >= BUF_SIZE) then Exit; + if (B^.WritePos + N > B^.Cap) then + B^.Cap := B^.WritePos + N + 1; + + CopyMemory(Pointer(NativeUInt(Addr(B^.Data)) + B^.WritePos), + Addr(V^.Data), N); + + B^.WritePos := B^.WritePos + N; +end; + function e_Buffer_Read_Char(B: pTBuffer): Char; begin @@ -237,8 +258,8 @@ begin Result := ''; if Len = 0 then Exit; - if B^.ReadPos + Len > B^.Len then - Len := B^.Len - B^.ReadPos; + if B^.ReadPos + Len > B^.Cap then + Len := B^.Cap - B^.ReadPos; SetLength(Result, Len); CopyMemory(@Result[1], Pointer(NativeUInt(Addr(B^.Data)) + B^.ReadPos), Len); diff --git a/src/game/g_game.pas b/src/game/g_game.pas index 18f5639..36b1016 100644 --- a/src/game/g_game.pas +++ b/src/game/g_game.pas @@ -3639,6 +3639,7 @@ var State: Byte; OuterLoop: Boolean; newResPath: string; + Len: Word; begin g_Game_Free(); @@ -3688,6 +3689,7 @@ begin Ptr := NetEvent.packet^.data; e_Raw_Seek(0); + Len := e_Raw_Read_Word(Ptr); MID := e_Raw_Read_Byte(Ptr); if (MID = NET_MSG_INFO) and (State = 0) then @@ -3794,7 +3796,7 @@ begin g_Player_Init(); NetState := NET_STATE_GAME; - MC_SEND_FullStateRequest; + MC_SEND_FullStateRequest(); e_WriteLog('NET: Connection successful.', MSG_NOTIFY); end; diff --git a/src/game/g_net.pas b/src/game/g_net.pas index 3596849..ee7ee2a 100644 --- a/src/game/g_net.pas +++ b/src/game/g_net.pas @@ -25,7 +25,6 @@ const NET_PROTOCOL_VER = 171; NET_MAXCLIENTS = 24; - NET_CHANS = 11; NET_CHAN_SERVICE = 0; NET_CHAN_IMPORTANT = 1; @@ -39,6 +38,13 @@ const NET_CHAN_DOWNLOAD = 9; NET_CHAN_SHOTS = 10; + CH_RELIABLE = 0; + CH_UNRELIABLE = 1; + CH_DOWNLOAD = 2; + CH_MAX = CH_UNRELIABLE; // don't change this + + NET_CHANS = 3; + NET_NONE = 0; NET_SERVER = 1; NET_CLIENT = 2; @@ -67,14 +73,15 @@ const type TNetClient = record - ID: Byte; - Used: Boolean; - State: Byte; - Peer: pENetPeer; - Player: Word; + ID: Byte; + Used: Boolean; + State: Byte; + Peer: pENetPeer; + Player: Word; RequestedFullUpdate: Boolean; RCONAuth: Boolean; Voted: Boolean; + SendBuf: array [0..CH_MAX] of TBuffer; end; TBanRecord = record IP: LongWord; @@ -117,11 +124,12 @@ var NetClientPort: Word = 25666; NetIn, NetOut: TBuffer; + NetSend: array [0..CH_MAX] of TBuffer; - NetClients: array of TNetClient; + NetClients: array of TNetClient = nil; NetClientCount: Byte = 0; NetMaxClients: Byte = 255; - NetBannedHosts: array of TBanRecord; + NetBannedHosts: array of TBanRecord = nil; NetState: Integer = NET_STATE_NONE; @@ -151,12 +159,14 @@ function g_Net_Host(IPAddr: LongWord; Port: enet_uint16; MaxClients: Cardinal = procedure g_Net_Host_Die(); procedure g_Net_Host_Send(ID: Integer; Reliable: Boolean; Chan: Byte = NET_CHAN_GAME); function g_Net_Host_Update(): enet_size_t; +procedure g_Net_Host_FlushBuffers(); 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); function g_Net_Client_Update(): enet_size_t; function g_Net_Client_UpdateWhileLoading(): enet_size_t; +procedure g_Net_Client_FlushBuffers(); function g_Net_Client_ByName(Name: string): pTNetClient; function g_Net_Client_ByPlayer(PID: Word): pTNetClient; @@ -192,6 +202,27 @@ uses { /// SERVICE FUNCTIONS /// } +procedure SendBuffer(B: pTBuffer; Ch: Integer; Peer: pENetPeer); +var + P: pENetPacket; + Fl: enet_uint32; +begin + if Ch = CH_RELIABLE then Fl := ENET_PACKET_FLAG_RELIABLE + else Fl := 0; + if B^.WritePos > 0 then + begin + P := enet_packet_create(Addr(B^.Data), B^.WritePos, Fl); + if P <> nil then + begin + if Peer = nil then + enet_host_broadcast(NetHost, Ch, P) + else + enet_peer_send(Peer, Ch, P); + end; + e_Buffer_Clear(B); + end; +end; + function g_Net_FindSlot(): Integer; var I: Integer; @@ -237,6 +268,9 @@ begin NetClients[N].RCONAuth := False; NetClients[N].Voted := False; NetClients[N].Player := 0; + NetClients[N].Peer := nil; + for I := 0 to CH_MAX do + e_Buffer_Clear(Addr(NetClients[N].SendBuf[CH_MAX])); end; Result := N; @@ -247,9 +281,12 @@ var F: TextFile; IPstr: string; IP: LongWord; + I: Integer; begin e_Buffer_Clear(@NetIn); e_Buffer_Clear(@NetOut); + for I := 0 to CH_MAX do + e_Buffer_Clear(@NetSend[i]); SetLength(NetClients, 0); NetPeer := nil; NetHost := nil; @@ -277,13 +314,21 @@ end; procedure g_Net_Flush(); begin + if NetMode = NET_SERVER then + g_Net_Host_FlushBuffers() + else + g_Net_Client_FlushBuffers(); enet_host_flush(NetHost); end; procedure g_Net_Cleanup(); +var + I: Integer; begin e_Buffer_Clear(@NetIn); e_Buffer_Clear(@NetOut); + for i := 0 to CH_MAX do + e_Buffer_Clear(@NetSend[i]); SetLength(NetClients, 0); NetClientCount := 0; @@ -417,37 +462,48 @@ begin e_WriteLog('NET: Server stopped', MSG_NOTIFY); end; +procedure g_Net_Host_FlushBuffers(); +var + I: Integer; +begin + // send broadcast + SendBuffer(@NetSend[CH_RELIABLE], CH_RELIABLE, nil); + SendBuffer(@NetSend[CH_UNRELIABLE], CH_UNRELIABLE, nil); + // send to individual clients + if NetClients <> nil then + for I := Low(NetClients) to High(NetClients) do + with NetClients[I] do + begin + SendBuffer(@SendBuf[CH_RELIABLE], CH_RELIABLE, Peer); + SendBuffer(@SendBuf[CH_UNRELIABLE], CH_UNRELIABLE, Peer); + end; +end; procedure g_Net_Host_Send(ID: Integer; Reliable: Boolean; Chan: Byte = NET_CHAN_GAME); var - P: pENetPacket; - F: enet_uint32; + I: Integer; + B: pTBuffer; begin if (Reliable) then - F := LongWord(ENET_PACKET_FLAG_RELIABLE) + I := CH_RELIABLE else - F := 0; + I := CH_UNRELIABLE; if (ID >= 0) then begin - if ID > High(NetClients) then Exit; - if NetClients[ID].Peer = nil then Exit; - - P := enet_packet_create(Addr(NetOut.Data), NetOut.Len, F); - if not Assigned(P) then Exit; - - enet_peer_send(NetClients[ID].Peer, Chan, P); + if (ID > High(NetClients)) or (NetClients[ID].Peer = nil) then + begin + e_Buffer_Clear(@NetOut); + Exit; + end; + B := Addr(NetClients[ID].SendBuf[I]); end else begin - P := enet_packet_create(Addr(NetOut.Data), NetOut.Len, F); - if not Assigned(P) then Exit; - - enet_host_broadcast(NetHost, Chan, P); + B := Addr(NetSend[I]); end; - if NetDump then g_Net_DumpSendBuffer(); - g_Net_Flush(); + e_Buffer_Write(B, @NetOut); e_Buffer_Clear(@NetOut); end; @@ -497,7 +553,7 @@ function g_Net_Host_Update(): enet_size_t; var IP: string; Port: Word; - ID: Integer; + ID, I: Integer; TC: pTNetClient; TP: TPlayer; begin @@ -561,8 +617,6 @@ begin ID := Byte(NetEvent.peer^.data^); 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; @@ -653,22 +707,21 @@ begin e_WriteLog('NET: Disconnected', MSG_NOTIFY); end; +procedure g_Net_Client_FlushBuffers(); +begin + SendBuffer(@NetSend[CH_RELIABLE], CH_RELIABLE, NetPeer); + SendBuffer(@NetSend[CH_UNRELIABLE], CH_UNRELIABLE, NetPeer); +end; + procedure g_Net_Client_Send(Reliable: Boolean; Chan: Byte = NET_CHAN_GAME); var - P: pENetPacket; - F: enet_uint32; + I: Integer; begin if (Reliable) then - F := LongWord(ENET_PACKET_FLAG_RELIABLE) + I := CH_RELIABLE else - F := 0; - - P := enet_packet_create(Addr(NetOut.Data), NetOut.Len, F); - if not Assigned(P) then Exit; - - enet_peer_send(NetPeer, Chan, P); - if NetDump then g_Net_DumpSendBuffer(); - g_Net_Flush(); + I := CH_UNRELIABLE; + e_Buffer_Write(@NetSend[I], @NetOut); e_Buffer_Clear(@NetOut); end; @@ -680,7 +733,6 @@ 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; @@ -702,7 +754,6 @@ 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; @@ -714,7 +765,6 @@ begin end; end; end; - g_Net_Flush(); end; function g_Net_Connect(IP: string; Port: enet_uint16): Boolean; @@ -897,13 +947,13 @@ begin begin P := enet_packet_create(@Data[0], dataLength, F); if not Assigned(P) then Exit; - enet_peer_send(peer, Chan, P); + enet_peer_send(peer, CH_DOWNLOAD, P); end else begin P := enet_packet_create(@Data[0], dataLength, F); if not Assigned(P) then Exit; - enet_host_broadcast(NetHost, Chan, P); + enet_host_broadcast(NetHost, CH_DOWNLOAD, P); end; enet_host_flush(NetHost); @@ -924,17 +974,16 @@ begin begin while (enet_host_service(NetHost, @downloadEvent, 0) > 0) do begin - if (downloadEvent.kind = ENET_EVENT_TYPE_RECEIVE) then + if (downloadEvent.kind = ENET_EVENT_TYPE_RECEIVE) and (downloadEvent.packet^.dataLength > 2) then begin - Ptr := downloadEvent.packet^.data; - + Ptr := downloadEvent.packet^.data + 2; // skip length MID := Byte(Ptr^); if (MID = msgId) then begin msgStream := TMemoryStream.Create; - msgStream.SetSize(downloadEvent.packet^.dataLength); - msgStream.WriteBuffer(Ptr^, downloadEvent.packet^.dataLength); + msgStream.SetSize(downloadEvent.packet^.dataLength - 2); + msgStream.WriteBuffer(Ptr^, downloadEvent.packet^.dataLength - 2); msgStream.Seek(0, soFromBeginning); OuterLoop := False; @@ -1085,9 +1134,9 @@ end; procedure g_Net_DumpSendBuffer(); begin writeInt(NetDumpFile, gTime); - writeInt(NetDumpFile, LongWord(NetOut.Len)); + writeInt(NetDumpFile, LongWord(NetOut.WritePos)); writeInt(NetDumpFile, Byte(1)); - NetDumpFile.WriteBuffer(NetOut.Data[0], NetOut.Len); + NetDumpFile.WriteBuffer(NetOut.Data[0], NetOut.WritePos); end; procedure g_Net_DumpRecvBuffer(Buf: penet_uint8; Len: LongWord); diff --git a/src/game/g_nethandler.pas b/src/game/g_nethandler.pas index a4711af..f505d62 100644 --- a/src/game/g_nethandler.pas +++ b/src/game/g_nethandler.pas @@ -26,11 +26,12 @@ procedure g_Net_HostMsgHandler(S: pTNetClient; P: pENetPacket); implementation -uses e_fixedbuffer; +uses e_fixedbuffer, e_log, StrUtils, SysUtils; procedure g_Net_ClientMsgHandler(P: pENetPacket); var MID: Byte; + Len: Word; B: Pointer; begin e_Raw_Seek(0); @@ -38,48 +39,51 @@ begin B := P^.data; if B = nil then Exit; - MID := e_Raw_Read_Byte(B); - - case MID of - NET_MSG_CHAT: MC_RECV_Chat(B); - NET_MSG_GFX: MC_RECV_Effect(B); - NET_MSG_SND: MC_RECV_Sound(B); - NET_MSG_SCORE: MC_RECV_GameStats(B); - NET_MSG_COOP: MC_RECV_CoopStats(B); - NET_MSG_GEVENT: MC_RECV_GameEvent(B); - NET_MSG_FLAG: MC_RECV_FlagEvent(B); - NET_MSG_GSET: MC_RECV_GameSettings(B); - - NET_MSG_PLR: MC_RECV_PlayerCreate(B); - NET_MSG_PLRPOS: MC_RECV_PlayerPos(B); - NET_MSG_PLRSTA: MC_RECV_PlayerStats(B); - NET_MSG_PLRDEL: MC_RECV_PlayerDelete(B); - NET_MSG_PLRDMG: MC_RECV_PlayerDamage(B); - NET_MSG_PLRDIE: MC_RECV_PlayerDeath(B); - NET_MSG_PLRFIRE:MC_RECV_PlayerFire(B); - NET_MSG_PLRSET: MC_RECV_PlayerSettings(B); - - NET_MSG_MSPAWN: MC_RECV_MonsterSpawn(B); - NET_MSG_MPOS: MC_RECV_MonsterPos(B); - NET_MSG_MSTATE: MC_RECV_MonsterState(B); - NET_MSG_MSHOT: MC_RECV_MonsterShot(B); - NET_MSG_MDEL: MC_RECV_MonsterDelete(B); - - NET_MSG_SHADD: MC_RECV_CreateShot(B); - NET_MSG_SHPOS: MC_RECV_UpdateShot(B); - NET_MSG_SHDEL: MC_RECV_DeleteShot(B); - - NET_MSG_ISPAWN: MC_RECV_ItemSpawn(B); - NET_MSG_IDEL: MC_RECV_ItemDestroy(B); - - NET_MSG_PSTATE: MC_RECV_PanelState(B); - NET_MSG_PTEX: MC_RECV_PanelTexture(B); - - NET_MSG_TSOUND: MC_RECV_TriggerSound(B); - NET_MSG_TMUSIC: MC_RECV_TriggerMusic(B); - - NET_MSG_TIME_SYNC: MC_RECV_TimeSync(B); - NET_MSG_VOTE_EVENT: MC_RECV_VoteEvent(B); + while RawPos < P^.dataLength do + begin + Len := e_Raw_Read_Word(B); + MID := e_Raw_Read_Byte(B); + case MID of + NET_MSG_CHAT: MC_RECV_Chat(B); + NET_MSG_GFX: MC_RECV_Effect(B); + NET_MSG_SND: MC_RECV_Sound(B); + NET_MSG_SCORE: MC_RECV_GameStats(B); + NET_MSG_COOP: MC_RECV_CoopStats(B); + NET_MSG_GEVENT: MC_RECV_GameEvent(B); + NET_MSG_FLAG: MC_RECV_FlagEvent(B); + NET_MSG_GSET: MC_RECV_GameSettings(B); + + NET_MSG_PLR: MC_RECV_PlayerCreate(B); + NET_MSG_PLRPOS: MC_RECV_PlayerPos(B); + NET_MSG_PLRSTA: MC_RECV_PlayerStats(B); + NET_MSG_PLRDEL: MC_RECV_PlayerDelete(B); + NET_MSG_PLRDMG: MC_RECV_PlayerDamage(B); + NET_MSG_PLRDIE: MC_RECV_PlayerDeath(B); + NET_MSG_PLRFIRE:MC_RECV_PlayerFire(B); + NET_MSG_PLRSET: MC_RECV_PlayerSettings(B); + + NET_MSG_MSPAWN: MC_RECV_MonsterSpawn(B); + NET_MSG_MPOS: MC_RECV_MonsterPos(B); + NET_MSG_MSTATE: MC_RECV_MonsterState(B); + NET_MSG_MSHOT: MC_RECV_MonsterShot(B); + NET_MSG_MDEL: MC_RECV_MonsterDelete(B); + + NET_MSG_SHADD: MC_RECV_CreateShot(B); + NET_MSG_SHPOS: MC_RECV_UpdateShot(B); + NET_MSG_SHDEL: MC_RECV_DeleteShot(B); + + NET_MSG_ISPAWN: MC_RECV_ItemSpawn(B); + NET_MSG_IDEL: MC_RECV_ItemDestroy(B); + + NET_MSG_PSTATE: MC_RECV_PanelState(B); + NET_MSG_PTEX: MC_RECV_PanelTexture(B); + + NET_MSG_TSOUND: MC_RECV_TriggerSound(B); + NET_MSG_TMUSIC: MC_RECV_TriggerMusic(B); + + NET_MSG_TIME_SYNC: MC_RECV_TimeSync(B); + NET_MSG_VOTE_EVENT: MC_RECV_VoteEvent(B); + end; end; enet_packet_destroy(P); @@ -88,6 +92,7 @@ end; procedure g_Net_ClientLightMsgHandler(P: pENetPacket); var MID: Byte; + Len: Word; B: Pointer; begin e_Raw_Seek(0); @@ -95,14 +100,19 @@ begin B := P^.data; if B = nil then Exit; - MID := e_Raw_Read_Byte(B); + while RawPos < P^.dataLength do + begin + Len := e_Raw_Read_Word(B); + MID := e_Raw_Read_Byte(B); + case MID of + NET_MSG_GEVENT: MC_RECV_GameEvent(B); + NET_MSG_GSET: MC_RECV_GameSettings(B); - case MID of - NET_MSG_GEVENT: MC_RECV_GameEvent(B); - NET_MSG_GSET: MC_RECV_GameSettings(B); + NET_MSG_PLR: if NetState <> NET_STATE_AUTH then MC_RECV_PlayerCreate(B); + NET_MSG_PLRDEL: if NetState <> NET_STATE_AUTH then MC_RECV_PlayerDelete(B); - NET_MSG_PLR: if NetState <> NET_STATE_AUTH then MC_RECV_PlayerCreate(B); - NET_MSG_PLRDEL: if NetState <> NET_STATE_AUTH then MC_RECV_PlayerDelete(B); + else RawPos := RawPos + Len; + end; end; enet_packet_destroy(P); @@ -111,6 +121,7 @@ end; procedure g_Net_HostMsgHandler(S: pTNetClient; P: pENetPacket); var MID: Byte; + Len: Word; B: Pointer; begin e_Raw_Seek(0); @@ -118,24 +129,27 @@ begin B := P^.data; if B = nil then Exit; - MID := e_Raw_Read_Byte(B); + while RawPos < P^.dataLength do + begin + Len := e_Raw_Read_Word(B); + MID := e_Raw_Read_Byte(B); + case MID of + NET_MSG_INFO: MH_RECV_Info(S, B); + NET_MSG_CHAT: MH_RECV_Chat(S, B); + NET_MSG_REQFST: MH_RECV_FullStateRequest(S, B); - case MID of - NET_MSG_INFO: MH_RECV_Info(S, B); - NET_MSG_CHAT: MH_RECV_Chat(S, B); - NET_MSG_REQFST: MH_RECV_FullStateRequest(S, B); + NET_MSG_PLRPOS: MH_RECV_PlayerPos(S, B); + NET_MSG_PLRSET: MH_RECV_PlayerSettings(S, B); + NET_MSG_CHEAT: MH_RECV_CheatRequest(S, B); - NET_MSG_PLRPOS: MH_RECV_PlayerPos(S, B); - NET_MSG_PLRSET: MH_RECV_PlayerSettings(S, B); - NET_MSG_CHEAT: MH_RECV_CheatRequest(S, B); + NET_MSG_RCON_AUTH: MH_RECV_RCONPassword(S, B); + NET_MSG_RCON_CMD: MH_RECV_RCONCommand(S, B); - NET_MSG_RCON_AUTH: MH_RECV_RCONPassword(S, B); - NET_MSG_RCON_CMD: MH_RECV_RCONCommand(S, B); + NET_MSG_MAP_REQUEST: MH_RECV_MapRequest(S, B); + NET_MSG_RES_REQUEST: MH_RECV_ResRequest(S, B); - NET_MSG_MAP_REQUEST: MH_RECV_MapRequest(S, B); - NET_MSG_RES_REQUEST: MH_RECV_ResRequest(S, B); - - NET_MSG_VOTE_EVENT: MH_RECV_Vote(S, B); + NET_MSG_VOTE_EVENT: MH_RECV_Vote(S, B); + end; end; enet_packet_destroy(P); diff --git a/src/game/g_netmaster.pas b/src/game/g_netmaster.pas index 64681c3..bc7d4ae 100644 --- a/src/game/g_netmaster.pas +++ b/src/game/g_netmaster.pas @@ -130,7 +130,7 @@ begin e_Buffer_Clear(@NetOut); e_Buffer_Write(@NetOut, Byte(NET_MMSG_GET)); - P := enet_packet_create(Addr(NetOut.Data), NetOut.Len, Cardinal(ENET_PACKET_FLAG_RELIABLE)); + P := enet_packet_create(Addr(NetOut.Data), NetOut.WritePos, Cardinal(ENET_PACKET_FLAG_RELIABLE)); enet_peer_send(NetMPeer, NET_MCHAN_MAIN, P); enet_host_flush(NetMHost); @@ -201,7 +201,7 @@ begin RX := enet_socket_receive(Sock, @SvAddr, @Buf, 1); if RX <= 0 then continue; - NetIn.Len := RX + 1; + NetIn.Cap := RX + 1; NetIn.ReadPos := 0; if e_Buffer_Read_Char(@NetIn) <> 'D' then continue; @@ -269,7 +269,7 @@ begin g_Net_Slist_WriteInfo(); - P := enet_packet_create(Addr(NetOut.Data), NetOut.Len, Cardinal(ENET_PACKET_FLAG_RELIABLE)); + P := enet_packet_create(Addr(NetOut.Data), NetOut.WritePos, Cardinal(ENET_PACKET_FLAG_RELIABLE)); enet_peer_send(NetMPeer, NET_MCHAN_UPD, P); enet_host_flush(NetMHost); @@ -285,7 +285,7 @@ begin e_Buffer_Write(@NetOut, Byte(NET_MMSG_DEL)); e_Buffer_Write(@NetOut, NetAddr.port); - P := enet_packet_create(Addr(NetOut.Data), NetOut.Len, Cardinal(ENET_PACKET_FLAG_RELIABLE)); + P := enet_packet_create(Addr(NetOut.Data), NetOut.WritePos, Cardinal(ENET_PACKET_FLAG_RELIABLE)); enet_peer_send(NetMPeer, NET_MCHAN_MAIN, P); enet_host_flush(NetMHost); diff --git a/src/game/g_netmsg.pas b/src/game/g_netmsg.pas index 3049838..b4612d3 100644 --- a/src/game/g_netmsg.pas +++ b/src/game/g_netmsg.pas @@ -2777,6 +2777,7 @@ begin e_Buffer_Write(@NetOut, gPlayer1Settings.Team); g_Net_Client_Send(True, NET_CHAN_SERVICE); + g_Net_Flush(); // send immediately, there's no frames yet end; procedure MC_SEND_Chat(Txt: string; Mode: Byte); @@ -2914,6 +2915,7 @@ begin e_Buffer_Write(@NetOut, Byte(NET_MSG_REQFST)); g_Net_Client_Send(True, NET_CHAN_SERVICE); + g_Net_Flush(); // send immediately, because loading end; procedure MC_SEND_CheatRequest(Kind: Byte); @@ -2986,9 +2988,11 @@ end; procedure ResDataMsgToBytes(var bytes: AByte; const ResData: TResDataMsg); var ResultStream: TMemoryStream; + dummy: Word = $FFFE; begin ResultStream := TMemoryStream.Create; + ResultStream.WriteBuffer(dummy, 2); //dummy length ResultStream.WriteBuffer(ResData.MsgId, SizeOf(ResData.MsgId)); //msgId ResultStream.WriteBuffer(ResData.FileSize, SizeOf(ResData.FileSize)); //file size ResultStream.WriteBuffer(ResData.FileData[0], ResData.FileSize); //file data @@ -3012,11 +3016,13 @@ procedure MapDataMsgToBytes(var bytes: AByte; const MapDataMsg: TMapDataMsg); var ResultStream: TMemoryStream; resCount: Integer; + dummy: Word = $FFFF; begin resCount := Length(MapDataMsg.ExternalResources); ResultStream := TMemoryStream.Create; + ResultStream.WriteBuffer(dummy, 2); //dummy length ResultStream.WriteBuffer(MapDataMsg.MsgId, SizeOf(MapDataMsg.MsgId)); //msgId ResultStream.WriteBuffer(MapDataMsg.FileSize, SizeOf(MapDataMsg.FileSize)); //file size ResultStream.WriteBuffer(MapDataMsg.FileData[0], MapDataMsg.FileSize); //file data diff --git a/src/game/g_window.pas b/src/game/g_window.pas index 89511af..a8c6b6a 100644 --- a/src/game/g_window.pas +++ b/src/game/g_window.pas @@ -545,10 +545,17 @@ begin e_SoundUpdate(); if NetMode = NET_SERVER then - g_Net_Host_Update - else - if (NetMode = NET_CLIENT) and (NetState <> NET_STATE_AUTH) then - g_Net_Client_UpdateWhileLoading; + begin + g_Net_Host_Update(); + g_Net_Flush(); + end + else if NetMode = NET_CLIENT then + if (NetState <> NET_STATE_AUTH) then + begin + g_Net_Client_UpdateWhileLoading(); + g_Net_Flush(); + end; + wLoadingProgress := False; end; @@ -586,12 +593,14 @@ begin if NetMode = NET_SERVER then g_Net_Host_Update() else if NetMode = NET_CLIENT then g_Net_Client_Update(); Update(); + if NetMode <> NET_NONE then g_Net_Flush(); end; end - else + else if NetMode <> NET_NONE then begin if NetMode = NET_SERVER then g_Net_Host_Update() else if NetMode = NET_CLIENT then g_Net_Client_Update(); + g_Net_Flush(); end; if wLoadingQuit then