summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 9e08e52)
raw | patch | inline | side by side (parent: 9e08e52)
author | fgsfds <pvt.fgsfds@gmail.com> | |
Wed, 16 Aug 2017 17:44:19 +0000 (20:44 +0300) | ||
committer | fgsfds <pvt.fgsfds@gmail.com> | |
Wed, 16 Aug 2017 17:44:19 +0000 (20:44 +0300) |
index c59302102436e38a1ad715ec74df08c7e908d315..3b6dbf801b28d8208d13ce71236afde048b5bd3e 100644 (file)
Data: array [0..BUF_SIZE] of Byte; // îäèí áàéò ñâåðõó íà âñÿêèé ñëó÷àé
ReadPos: Cardinal;
WritePos: Cardinal;
- Len: Cardinal;
+ Cap: Cardinal;
end;
pTBuffer = ^TBuffer;
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;
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);
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);
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
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 18f56398b60c03eec7734ebc8eada624a9e2b82d..36b1016abb6720dab7e7006448c8ef2ad7e966c5 100644 (file)
--- a/src/game/g_game.pas
+++ b/src/game/g_game.pas
State: Byte;
OuterLoop: Boolean;
newResPath: string;
+ Len: Word;
begin
g_Game_Free();
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
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 35968491ebc828dc90f30cbcf5cd56d2d447db16..ee7ee2a5bc67c2faf5f337453042141f83bb81e7 100644 (file)
--- a/src/game/g_net.pas
+++ b/src/game/g_net.pas
NET_PROTOCOL_VER = 171;
NET_MAXCLIENTS = 24;
- NET_CHANS = 11;
NET_CHAN_SERVICE = 0;
NET_CHAN_IMPORTANT = 1;
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;
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;
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;
{ /// 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;
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;
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;
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;
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;
var
IP: string;
Port: Word;
- ID: Integer;
+ ID, I: Integer;
TC: pTNetClient;
TP: TPlayer;
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;
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;
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;
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;
end;
end;
end;
- g_Net_Flush();
end;
function g_Net_Connect(IP: string; Port: enet_uint16): Boolean;
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);
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;
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);
index a4711af631f8eecaeeb15156fa333871c4f316b8..f505d62ecc848f9d4812fb6fbfcebea405a38149 100644 (file)
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);
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);
procedure g_Net_ClientLightMsgHandler(P: pENetPacket);
var
MID: Byte;
+ Len: Word;
B: Pointer;
begin
e_Raw_Seek(0);
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);
procedure g_Net_HostMsgHandler(S: pTNetClient; P: pENetPacket);
var
MID: Byte;
+ Len: Word;
B: Pointer;
begin
e_Raw_Seek(0);
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);
index 64681c3946e49dc51d88e16a0bf428249471d307..bc7d4ae30aaa7e19d9d8671d5e32106ab5166b1f 100644 (file)
--- a/src/game/g_netmaster.pas
+++ b/src/game/g_netmaster.pas
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);
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;
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);
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 3049838d8ce65254c5b48877aec87f35b0a51277..b4612d3ec5cc8e7d676cc89ccac23d6f71d9066b 100644 (file)
--- a/src/game/g_netmsg.pas
+++ b/src/game/g_netmsg.pas
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);
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);
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 89511af81cd2c15fc309ba95ad06e9c2009db0c5..a8c6b6a7b3c3bf8302e95d712e2a2b875750359a 100644 (file)
--- a/src/game/g_window.pas
+++ b/src/game/g_window.pas
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;
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