From: havoc Date: Thu, 23 Feb 2006 10:57:31 +0000 (+0000) Subject: merged NetConn_SendReliableMessage into NetConn_SendUnreliableMessage, and also merge... X-Git-Tag: xonotic-v0.1.0preview~4298 X-Git-Url: http://de.git.xonotic.org/?p=xonotic%2Fdarkplaces.git;a=commitdiff_plain;h=50804f7075a727286ca58efcf890861afe314ee8 merged NetConn_SendReliableMessage into NetConn_SendUnreliableMessage, and also merged away the other ReliableMessage functions (ReSend and Next) rearranged client and server message sending calls to attempt to send unreliable messages, even if empty (necessary to trigger sending of reliable messages) eliminated last remnants of NetConn_SendToAll stuff changed some cls.demoplayback checks to !cls.netcon checks git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@6015 d7cf8633-e32d-0410-b094-e92efae38249 --- diff --git a/cl_input.c b/cl_input.c index c3fd63ac..19441cc1 100644 --- a/cl_input.c +++ b/cl_input.c @@ -802,30 +802,34 @@ void CL_SendMove(void) { int i; int bits; + int impulse; sizebuf_t buf; unsigned char data[128]; static double lastsendtime = 0; #define MOVEAVERAGING 0 #if MOVEAVERAGING - static float forwardmove, sidemove, upmove, total; // accumulation -#else - float forwardmove, sidemove, upmove; + static float accumforwardmove = 0, accumsidemove = 0, accumupmove = 0, accumtotal = 0; // accumulation #endif + float forwardmove, sidemove, upmove; + + // if playing a demo, do nothing + if (!cls.netcon) + return; #if MOVEAVERAGING // accumulate changes between messages - forwardmove += cl.cmd.forwardmove; - sidemove += cl.cmd.sidemove; - upmove += cl.cmd.upmove; - total++; + accumforwardmove += cl.cmd.forwardmove; + accumsidemove += cl.cmd.sidemove; + accumupmove += cl.cmd.upmove; + accumtotal++; #endif - if (cl_movement.integer) + if (cl_movement.integer && cls.signon == SIGNONS) { if (!cl.movement_needupdate) return; cl.movement_needupdate = false; - cl.movement = cl.stats[STAT_HEALTH] > 0 && !cls.demoplayback && !cl.intermission; + cl.movement = cl.stats[STAT_HEALTH] > 0 && !cl.intermission; } else { @@ -838,11 +842,14 @@ void CL_SendMove(void) } #if MOVEAVERAGING // average the accumulated changes - total = 1.0f / total; - forwardmove *= total; - sidemove *= total; - upmove *= total; - total = 0; + accumtotal = 1.0f / accumtotal; + forwardmove = accumforwardmove * accumtotal; + sidemove = accumsidemove * accumtotal; + upmove = accumupmove * accumtotal; + accumforwardmove = 0; + accumsidemove = 0; + accumupmove = 0; + accumtotal = 0; #else // use the latest values forwardmove = cl.cmd.forwardmove; @@ -885,144 +892,139 @@ void CL_SendMove(void) if (cl.cmd.cursor_screen[1] <= -1) bits |= 32; if (cl.cmd.cursor_screen[1] >= 1) bits |= 64; + impulse = in_impulse; + in_impulse = 0; + csqc_buttons = bits; - // always dump the first two messages, because they may contain leftover inputs from the last level - if (++cl.movemessages >= 2) + if (cls.signon == SIGNONS) { - // send the movement message - // PROTOCOL_QUAKE clc_move = 16 bytes total - // PROTOCOL_QUAKEDP clc_move = 16 bytes total - // PROTOCOL_NEHAHRAMOVIE clc_move = 16 bytes total - // PROTOCOL_DARKPLACES1 clc_move = 19 bytes total - // PROTOCOL_DARKPLACES2 clc_move = 25 bytes total - // PROTOCOL_DARKPLACES3 clc_move = 25 bytes total - // PROTOCOL_DARKPLACES4 clc_move = 19 bytes total - // PROTOCOL_DARKPLACES5 clc_move = 19 bytes total - // PROTOCOL_DARKPLACES6 clc_move = 52 bytes total - // PROTOCOL_DARKPLACES7 clc_move = 56 bytes total - if (cl.protocol == PROTOCOL_QUAKE || cl.protocol == PROTOCOL_QUAKEDP || cl.protocol == PROTOCOL_NEHAHRAMOVIE) - { - // 5 bytes - MSG_WriteByte (&buf, clc_move); - MSG_WriteFloat (&buf, cl.mtime[0]); // so server can get ping times - // 3 bytes - for (i = 0;i < 3;i++) - MSG_WriteAngle8i (&buf, cl.viewangles[i]); - // 6 bytes - MSG_WriteCoord16i (&buf, forwardmove); - MSG_WriteCoord16i (&buf, sidemove); - MSG_WriteCoord16i (&buf, upmove); - // 2 bytes - MSG_WriteByte (&buf, bits); - MSG_WriteByte (&buf, in_impulse); - } - else if (cl.protocol == PROTOCOL_DARKPLACES2 || cl.protocol == PROTOCOL_DARKPLACES3) - { - // 5 bytes - MSG_WriteByte (&buf, clc_move); - MSG_WriteFloat (&buf, cl.mtime[0]); // so server can get ping times - // 12 bytes - for (i = 0;i < 3;i++) - MSG_WriteAngle32f (&buf, cl.viewangles[i]); - // 6 bytes - MSG_WriteCoord16i (&buf, forwardmove); - MSG_WriteCoord16i (&buf, sidemove); - MSG_WriteCoord16i (&buf, upmove); - // 2 bytes - MSG_WriteByte (&buf, bits); - MSG_WriteByte (&buf, in_impulse); - } - else if (cl.protocol == PROTOCOL_DARKPLACES1 || cl.protocol == PROTOCOL_DARKPLACES4 || cl.protocol == PROTOCOL_DARKPLACES5) + // always dump the first two messages, because they may contain leftover inputs from the last level + if (++cl.movemessages >= 2) { - // 5 bytes - MSG_WriteByte (&buf, clc_move); - MSG_WriteFloat (&buf, cl.mtime[0]); // so server can get ping times - // 6 bytes - for (i = 0;i < 3;i++) - MSG_WriteAngle16i (&buf, cl.viewangles[i]); - // 6 bytes - MSG_WriteCoord16i (&buf, forwardmove); - MSG_WriteCoord16i (&buf, sidemove); - MSG_WriteCoord16i (&buf, upmove); - // 2 bytes - MSG_WriteByte (&buf, bits); - MSG_WriteByte (&buf, in_impulse); - } - else - { - // 5 bytes - MSG_WriteByte (&buf, clc_move); - if (cl.protocol != PROTOCOL_DARKPLACES6) + // send the movement message + // PROTOCOL_QUAKE clc_move = 16 bytes total + // PROTOCOL_QUAKEDP clc_move = 16 bytes total + // PROTOCOL_NEHAHRAMOVIE clc_move = 16 bytes total + // PROTOCOL_DARKPLACES1 clc_move = 19 bytes total + // PROTOCOL_DARKPLACES2 clc_move = 25 bytes total + // PROTOCOL_DARKPLACES3 clc_move = 25 bytes total + // PROTOCOL_DARKPLACES4 clc_move = 19 bytes total + // PROTOCOL_DARKPLACES5 clc_move = 19 bytes total + // PROTOCOL_DARKPLACES6 clc_move = 52 bytes total + // PROTOCOL_DARKPLACES7 clc_move = 56 bytes total + if (cl.protocol == PROTOCOL_QUAKE || cl.protocol == PROTOCOL_QUAKEDP || cl.protocol == PROTOCOL_NEHAHRAMOVIE) + { + // 5 bytes + MSG_WriteByte (&buf, clc_move); + MSG_WriteFloat (&buf, cl.mtime[0]); // so server can get ping times + // 3 bytes + for (i = 0;i < 3;i++) + MSG_WriteAngle8i (&buf, cl.viewangles[i]); + // 6 bytes + MSG_WriteCoord16i (&buf, forwardmove); + MSG_WriteCoord16i (&buf, sidemove); + MSG_WriteCoord16i (&buf, upmove); + // 2 bytes + MSG_WriteByte (&buf, bits); + MSG_WriteByte (&buf, impulse); + } + else if (cl.protocol == PROTOCOL_DARKPLACES2 || cl.protocol == PROTOCOL_DARKPLACES3) + { + // 5 bytes + MSG_WriteByte (&buf, clc_move); + MSG_WriteFloat (&buf, cl.mtime[0]); // so server can get ping times + // 12 bytes + for (i = 0;i < 3;i++) + MSG_WriteAngle32f (&buf, cl.viewangles[i]); + // 6 bytes + MSG_WriteCoord16i (&buf, forwardmove); + MSG_WriteCoord16i (&buf, sidemove); + MSG_WriteCoord16i (&buf, upmove); + // 2 bytes + MSG_WriteByte (&buf, bits); + MSG_WriteByte (&buf, impulse); + } + else if (cl.protocol == PROTOCOL_DARKPLACES1 || cl.protocol == PROTOCOL_DARKPLACES4 || cl.protocol == PROTOCOL_DARKPLACES5) + { + // 5 bytes + MSG_WriteByte (&buf, clc_move); + MSG_WriteFloat (&buf, cl.mtime[0]); // so server can get ping times + // 6 bytes + for (i = 0;i < 3;i++) + MSG_WriteAngle16i (&buf, cl.viewangles[i]); + // 6 bytes + MSG_WriteCoord16i (&buf, forwardmove); + MSG_WriteCoord16i (&buf, sidemove); + MSG_WriteCoord16i (&buf, upmove); + // 2 bytes + MSG_WriteByte (&buf, bits); + MSG_WriteByte (&buf, impulse); + } + else { - if (cl_movement.integer) + // 5 bytes + MSG_WriteByte (&buf, clc_move); + if (cl.protocol != PROTOCOL_DARKPLACES6) { - cl.movesequence++; - MSG_WriteLong (&buf, cl.movesequence); + if (cl_movement.integer) + { + cl.movesequence++; + MSG_WriteLong (&buf, cl.movesequence); + } + else + MSG_WriteLong (&buf, 0); } - else - MSG_WriteLong (&buf, 0); + MSG_WriteFloat (&buf, cl.mtime[0]); // so server can get ping times + // 6 bytes + for (i = 0;i < 3;i++) + MSG_WriteAngle16i (&buf, cl.viewangles[i]); + // 6 bytes + MSG_WriteCoord16i (&buf, forwardmove); + MSG_WriteCoord16i (&buf, sidemove); + MSG_WriteCoord16i (&buf, upmove); + // 5 bytes + MSG_WriteLong (&buf, bits); + MSG_WriteByte (&buf, impulse); + // PRYDON_CLIENTCURSOR + // 30 bytes + MSG_WriteShort (&buf, cl.cmd.cursor_screen[0] * 32767.0f); + MSG_WriteShort (&buf, cl.cmd.cursor_screen[1] * 32767.0f); + MSG_WriteFloat (&buf, cl.cmd.cursor_start[0]); + MSG_WriteFloat (&buf, cl.cmd.cursor_start[1]); + MSG_WriteFloat (&buf, cl.cmd.cursor_start[2]); + MSG_WriteFloat (&buf, cl.cmd.cursor_impact[0]); + MSG_WriteFloat (&buf, cl.cmd.cursor_impact[1]); + MSG_WriteFloat (&buf, cl.cmd.cursor_impact[2]); + MSG_WriteShort (&buf, cl.cmd.cursor_entitynumber); } - MSG_WriteFloat (&buf, cl.mtime[0]); // so server can get ping times - // 6 bytes - for (i = 0;i < 3;i++) - MSG_WriteAngle16i (&buf, cl.viewangles[i]); - // 6 bytes - MSG_WriteCoord16i (&buf, forwardmove); - MSG_WriteCoord16i (&buf, sidemove); - MSG_WriteCoord16i (&buf, upmove); - // 5 bytes - MSG_WriteLong (&buf, bits); - MSG_WriteByte (&buf, in_impulse); - // PRYDON_CLIENTCURSOR - // 30 bytes - MSG_WriteShort (&buf, cl.cmd.cursor_screen[0] * 32767.0f); - MSG_WriteShort (&buf, cl.cmd.cursor_screen[1] * 32767.0f); - MSG_WriteFloat (&buf, cl.cmd.cursor_start[0]); - MSG_WriteFloat (&buf, cl.cmd.cursor_start[1]); - MSG_WriteFloat (&buf, cl.cmd.cursor_start[2]); - MSG_WriteFloat (&buf, cl.cmd.cursor_impact[0]); - MSG_WriteFloat (&buf, cl.cmd.cursor_impact[1]); - MSG_WriteFloat (&buf, cl.cmd.cursor_impact[2]); - MSG_WriteShort (&buf, cl.cmd.cursor_entitynumber); - } - } -#if MOVEAVERAGING - forwardmove = sidemove = upmove = 0; -#endif - in_impulse = 0; + // FIXME: bits & 16 is +button5, Nexuiz specific + CL_ClientMovement_Input((bits & 2) != 0, (bits & 16) != 0); + } - // ack the last few frame numbers - // (redundent to improve handling of client->server packet loss) - // for LATESTFRAMENUMS == 3 case this is 15 bytes - for (i = 0;i < LATESTFRAMENUMS;i++) - { - if (cl.latestframenums[i] > 0) + // ack the last few frame numbers + // (redundent to improve handling of client->server packet loss) + // for LATESTFRAMENUMS == 3 case this is 15 bytes + for (i = 0;i < LATESTFRAMENUMS;i++) { - if (developer_networkentities.integer >= 1) - Con_Printf("send clc_ackframe %i\n", cl.latestframenums[i]); - MSG_WriteByte(&buf, clc_ackframe); - MSG_WriteLong(&buf, cl.latestframenums[i]); + if (cl.latestframenums[i] > 0) + { + if (developer_networkentities.integer >= 1) + Con_Printf("send clc_ackframe %i\n", cl.latestframenums[i]); + MSG_WriteByte(&buf, clc_ackframe); + MSG_WriteLong(&buf, cl.latestframenums[i]); + } } - } - // PROTOCOL_DARKPLACES6 = 67 bytes per packet - // PROTOCOL_DARKPLACES7 = 71 bytes per packet - - // deliver the message - if (cls.demoplayback) - return; - // nothing to send - if (!buf.cursize) - return; - if (cls.signon != SIGNONS) - return; + // PROTOCOL_DARKPLACES6 = 67 bytes per packet + // PROTOCOL_DARKPLACES7 = 71 bytes per packet + } - // FIXME: bits & 16 is +button5, Nexuiz specific - CL_ClientMovement_Input((bits & 2) != 0, (bits & 16) != 0); + // send the reliable message (forwarded commands) if there is one + NetConn_SendUnreliableMessage(cls.netcon, &buf); - if (NetConn_SendUnreliableMessage(cls.netcon, &buf) == -1) + if (cls.netcon->message.overflowed) { Con_Print("CL_SendMove: lost server connection\n"); CL_Disconnect(); diff --git a/cl_main.c b/cl_main.c index 4509dedb..39882813 100644 --- a/cl_main.c +++ b/cl_main.c @@ -1480,7 +1480,7 @@ extern void CL_ClientMovement_Replay(); int CL_ReadFromServer(void) { CL_ReadDemoMessage(); - CL_SendCmd(); + CL_SendMove(); r_refdef.time = cl.time; r_refdef.extraupdate = !r_speeds.integer; @@ -1529,31 +1529,6 @@ int CL_ReadFromServer(void) return 0; } -/* -================= -CL_SendCmd -================= -*/ -void CL_UpdatePrydonCursor(void); -void CL_SendCmd(void) -{ - // send the reliable message (forwarded commands) if there is one - if (cls.netcon && cls.netcon->message.cursize && NetConn_CanSendMessage(cls.netcon)) - { - if (developer.integer) - { - Con_Print("CL_SendCmd: sending reliable message:\n"); - SZ_HexDumpToConsole(&cls.netcon->message); - } - if (NetConn_SendReliableMessage(cls.netcon, &cls.netcon->message) == -1) - Host_Error("CL_WriteToServer: lost server connection"); - SZ_Clear(&cls.netcon->message); - } - - // send a move periodically - CL_SendMove(); -} - // LordHavoc: pausedemo command static void CL_PauseDemo_f (void) { diff --git a/cl_parse.c b/cl_parse.c index 74f2c15f..5259676b 100644 --- a/cl_parse.c +++ b/cl_parse.c @@ -179,7 +179,7 @@ void CL_KeepaliveMessage (void) sizebuf_t old; // no need if server is local and definitely not if this is a demo - if (sv.active || cls.demoplayback) + if (sv.active || !cls.netcon) return; // read messages from server, should just be nops diff --git a/client.h b/client.h index 412afbdb..b917e488 100644 --- a/client.h +++ b/client.h @@ -780,7 +780,6 @@ extern kbutton_t in_strafe; extern kbutton_t in_speed; void CL_InitInput (void); -void CL_SendCmd (void); void CL_SendMove (void); void CL_ValidateState(entity_state_t *s); diff --git a/host_cmd.c b/host_cmd.c index f5f5fcc4..5aae255e 100644 --- a/host_cmd.c +++ b/host_cmd.c @@ -301,16 +301,16 @@ void Host_Changelevel_f (void) Con_Print("changelevel : continue game on a new level\n"); return; } - // HACKHACKHACK - if (!sv.active) { - Host_Map_f(); - return; - } if (cls.demoplayback) { Con_Print("Only the server may changelevel\n"); return; } + // HACKHACKHACK + if (!sv.active) { + Host_Map_f(); + return; + } if (cmd_source != src_command) return; @@ -348,7 +348,7 @@ void Host_Restart_f (void) Con_Print("restart : restart current level\n"); return; } - if (!sv.active || cls.demoplayback) + if (!sv.active) { Con_Print("Only the server may restart\n"); return; @@ -1280,7 +1280,6 @@ void Host_PreSpawn_f (void) MSG_WriteByte (&host_client->netconnection->message, svc_signonnum); MSG_WriteByte (&host_client->netconnection->message, 2); } - host_client->sendsignon = true; // reset the name change timer because the client will send name soon host_client->nametime = 0; @@ -1421,8 +1420,6 @@ void Host_Spawn_f (void) MSG_WriteByte (&host_client->netconnection->message, svc_signonnum); MSG_WriteByte (&host_client->netconnection->message, 3); - - host_client->sendsignon = true; } /* diff --git a/netconn.c b/netconn.c index 1915da7a..ef47f7e6 100755 --- a/netconn.c +++ b/netconn.c @@ -432,74 +432,15 @@ int NetConn_WriteString(lhnetsocket_t *mysocket, const char *string, const lhnet return NetConn_Write(mysocket, string, (int)strlen(string), peeraddress); } -int NetConn_SendReliableMessage(netconn_t *conn, sizebuf_t *data) -{ - unsigned int packetLen; - unsigned int dataLen; - unsigned int eom; - unsigned int *header; - -//#ifdef DEBUG - if (data->cursize == 0) - { - Con_Printf ("Datagram_SendMessage: zero length message\n"); - return -1; - } - - if (data->cursize > (int)sizeof(conn->sendMessage)) - { - Con_Printf ("Datagram_SendMessage: message too big (%u > %u)\n", data->cursize, sizeof(conn->sendMessage)); - return -1; - } - - if (conn->canSend == false) - { - Con_Printf ("SendMessage: called with canSend == false\n"); - return -1; - } -//#endif - - memcpy(conn->sendMessage, data->data, data->cursize); - conn->sendMessageLength = data->cursize; - - if (conn->sendMessageLength <= MAX_PACKETFRAGMENT) - { - dataLen = conn->sendMessageLength; - eom = NETFLAG_EOM; - } - else - { - dataLen = MAX_PACKETFRAGMENT; - eom = 0; - } - - packetLen = NET_HEADERSIZE + dataLen; - - header = (unsigned int *)sendbuffer; - header[0] = BigLong(packetLen | (NETFLAG_DATA | eom)); - header[1] = BigLong(conn->sendSequence); - memcpy(sendbuffer + NET_HEADERSIZE, conn->sendMessage, dataLen); - - conn->sendSequence++; - conn->canSend = false; - - if (NetConn_Write(conn->mysocket, (void *)&sendbuffer, packetLen, &conn->peeraddress) != (int)packetLen) - return -1; - - conn->lastSendTime = realtime; - packetsSent++; - reliableMessagesSent++; - return 1; -} - -static void NetConn_SendMessageNext(netconn_t *conn) +int NetConn_SendUnreliableMessage(netconn_t *conn, sizebuf_t *data) { unsigned int packetLen; unsigned int dataLen; unsigned int eom; unsigned int *header; - if (conn->sendMessageLength && !conn->canSend && conn->sendNext) + // if a reliable message fragment has been lost, send it again + if (!conn->canSend && conn->sendMessageLength && (realtime - conn->lastSendTime) > 1.0) { if (conn->sendMessageLength <= MAX_PACKETFRAGMENT) { @@ -516,29 +457,36 @@ static void NetConn_SendMessageNext(netconn_t *conn) header = (unsigned int *)sendbuffer; header[0] = BigLong(packetLen | (NETFLAG_DATA | eom)); - header[1] = BigLong(conn->sendSequence); + header[1] = BigLong(conn->sendSequence - 1); memcpy(sendbuffer + NET_HEADERSIZE, conn->sendMessage, dataLen); - conn->sendSequence++; - conn->sendNext = false; + if (NetConn_Write(conn->mysocket, (void *)&sendbuffer, packetLen, &conn->peeraddress) == (int)packetLen) + { + conn->lastSendTime = realtime; + packetsReSent++; + } + } - if (NetConn_Write(conn->mysocket, (void *)&sendbuffer, packetLen, &conn->peeraddress) != (int)packetLen) - return; + // if we have a new reliable message to send, do so + if (conn->canSend && conn->message.cursize) + { + if (conn->message.cursize > (int)sizeof(conn->sendMessage)) + { + Con_Printf("NetConn_SendUnreliableMessage: reliable message too big (%u > %u)\n", conn->message.cursize, sizeof(conn->sendMessage)); + conn->message.overflowed = true; + return -1; + } - conn->lastSendTime = realtime; - packetsSent++; - } -} + if (developer_networking.integer && conn == cls.netcon) + { + Con_Print("client sending reliable message to server:\n"); + SZ_HexDumpToConsole(&conn->message); + } -static void NetConn_ReSendMessage(netconn_t *conn) -{ - unsigned int packetLen; - unsigned int dataLen; - unsigned int eom; - unsigned int *header; + memcpy(conn->sendMessage, conn->message.data, conn->message.cursize); + conn->sendMessageLength = conn->message.cursize; + SZ_Clear(&conn->message); - if (conn->sendMessageLength && !conn->canSend && (realtime - conn->lastSendTime) > 1.0) - { if (conn->sendMessageLength <= MAX_PACKETFRAGMENT) { dataLen = conn->sendMessageLength; @@ -554,58 +502,43 @@ static void NetConn_ReSendMessage(netconn_t *conn) header = (unsigned int *)sendbuffer; header[0] = BigLong(packetLen | (NETFLAG_DATA | eom)); - header[1] = BigLong(conn->sendSequence - 1); + header[1] = BigLong(conn->sendSequence); memcpy(sendbuffer + NET_HEADERSIZE, conn->sendMessage, dataLen); - conn->sendNext = false; + conn->sendSequence++; + conn->canSend = false; - if (NetConn_Write(conn->mysocket, (void *)&sendbuffer, packetLen, &conn->peeraddress) != (int)packetLen) - return; + NetConn_Write(conn->mysocket, (void *)&sendbuffer, packetLen, &conn->peeraddress); conn->lastSendTime = realtime; - packetsReSent++; + packetsSent++; + reliableMessagesSent++; } -} - -qboolean NetConn_CanSendMessage(netconn_t *conn) -{ - return conn->canSend; -} - -int NetConn_SendUnreliableMessage(netconn_t *conn, sizebuf_t *data) -{ - int packetLen; - unsigned int *header; - - packetLen = NET_HEADERSIZE + data->cursize; -//#ifdef DEBUG - if (data->cursize == 0) + // if we have an unreliable message to send, do so + if (data->cursize) { - Con_Printf ("Datagram_SendUnreliableMessage: zero length message\n"); - return -1; - } + packetLen = NET_HEADERSIZE + data->cursize; - if (packetLen > (int)sizeof(sendbuffer)) - { - Con_Printf ("Datagram_SendUnreliableMessage: message too big %u\n", data->cursize); - return -1; - } -//#endif + if (packetLen > (int)sizeof(sendbuffer)) + { + Con_Printf("NetConn_SendUnreliableMessage: message too big %u\n", data->cursize); + return -1; + } - header = (unsigned int *)sendbuffer; - header[0] = BigLong(packetLen | NETFLAG_UNRELIABLE); - header[1] = BigLong(conn->unreliableSendSequence); - memcpy(sendbuffer + NET_HEADERSIZE, data->data, data->cursize); + header = (unsigned int *)sendbuffer; + header[0] = BigLong(packetLen | NETFLAG_UNRELIABLE); + header[1] = BigLong(conn->unreliableSendSequence); + memcpy(sendbuffer + NET_HEADERSIZE, data->data, data->cursize); - conn->unreliableSendSequence++; + conn->unreliableSendSequence++; - if (NetConn_Write(conn->mysocket, (void *)&sendbuffer, packetLen, &conn->peeraddress) != (int)packetLen) - return -1; + NetConn_Write(conn->mysocket, (void *)&sendbuffer, packetLen, &conn->peeraddress); - packetsSent++; - unreliableMessagesSent++; - return 1; + packetsSent++; + unreliableMessagesSent++; + } + return 0; } void NetConn_CloseClientPorts(void) @@ -805,7 +738,7 @@ void NetConn_UpdateSockets(void) } } -int NetConn_ReceivedMessage(netconn_t *conn, unsigned char *data, int length) +static int NetConn_ReceivedMessage(netconn_t *conn, unsigned char *data, int length) { unsigned int count; unsigned int flags; @@ -861,12 +794,41 @@ int NetConn_ReceivedMessage(netconn_t *conn, unsigned char *data, int length) Con_DPrint("ack sequencing error\n"); conn->lastMessageTime = realtime; conn->timeout = realtime + net_messagetimeout.value; - conn->sendMessageLength -= MAX_PACKETFRAGMENT; - if (conn->sendMessageLength > 0) + if (conn->sendMessageLength > MAX_PACKETFRAGMENT) { + unsigned int packetLen; + unsigned int dataLen; + unsigned int eom; + unsigned int *header; + + conn->sendMessageLength -= MAX_PACKETFRAGMENT; memcpy(conn->sendMessage, conn->sendMessage+MAX_PACKETFRAGMENT, conn->sendMessageLength); - conn->sendNext = true; - NetConn_SendMessageNext(conn); + + if (conn->sendMessageLength <= MAX_PACKETFRAGMENT) + { + dataLen = conn->sendMessageLength; + eom = NETFLAG_EOM; + } + else + { + dataLen = MAX_PACKETFRAGMENT; + eom = 0; + } + + packetLen = NET_HEADERSIZE + dataLen; + + header = (unsigned int *)sendbuffer; + header[0] = BigLong(packetLen | (NETFLAG_DATA | eom)); + header[1] = BigLong(conn->sendSequence); + memcpy(sendbuffer + NET_HEADERSIZE, conn->sendMessage, dataLen); + + conn->sendSequence++; + + if (NetConn_Write(conn->mysocket, (void *)&sendbuffer, packetLen, &conn->peeraddress) == (int)packetLen) + { + conn->lastSendTime = realtime; + packetsSent++; + } } else { @@ -950,7 +912,7 @@ int NetConn_IsLocalGame(void) return false; } -int NetConn_ClientParsePacket(lhnetsocket_t *mysocket, unsigned char *data, int length, lhnetaddress_t *peeraddress) +static int NetConn_ClientParsePacket(lhnetsocket_t *mysocket, unsigned char *data, int length, lhnetaddress_t *peeraddress) { int ret, c, control; const char *s; @@ -1289,7 +1251,6 @@ void NetConn_ClientFrame(void) { int i, length; lhnetaddress_t peeraddress; - netconn_t *conn; NetConn_UpdateSockets(); if (cls.connect_trying && cls.connect_nextsendtime < realtime) { @@ -1316,11 +1277,9 @@ void NetConn_ClientFrame(void) NetConn_Write(cls.connect_mysocket, net_message.data, net_message.cursize, &cls.connect_address); SZ_Clear(&net_message); } - for (i = 0;i < cl_numsockets;i++) { - while (cl_sockets[i] && (length = NetConn_Read(cl_sockets[i], readbuffer, sizeof(readbuffer), &peeraddress)) > 0) { + for (i = 0;i < cl_numsockets;i++) + while (cl_sockets[i] && (length = NetConn_Read(cl_sockets[i], readbuffer, sizeof(readbuffer), &peeraddress)) > 0) NetConn_ClientParsePacket(cl_sockets[i], readbuffer, length, &peeraddress); - } - } NetConn_QueryQueueFrame(); if (cls.netcon && realtime > cls.netcon->timeout) { @@ -1328,8 +1287,6 @@ void NetConn_ClientFrame(void) CL_Disconnect(); Host_ShutdownServer (); } - for (conn = netconn_list;conn;conn = conn->next) - NetConn_ReSendMessage(conn); } #define MAX_CHALLENGES 128 @@ -1430,7 +1387,7 @@ static qboolean NetConn_BuildStatusResponse(const char* challenge, char* out_msg } extern void SV_SendServerinfo (client_t *client); -int NetConn_ServerParsePacket(lhnetsocket_t *mysocket, unsigned char *data, int length, lhnetaddress_t *peeraddress) +static int NetConn_ServerParsePacket(lhnetsocket_t *mysocket, unsigned char *data, int length, lhnetaddress_t *peeraddress) { int i, ret, clientnum, best; double besttime; @@ -1827,7 +1784,6 @@ void NetConn_ServerFrame(void) { int i, length; lhnetaddress_t peeraddress; - netconn_t *conn; NetConn_UpdateSockets(); for (i = 0;i < sv_numsockets;i++) while (sv_sockets[i] && (length = NetConn_Read(sv_sockets[i], readbuffer, sizeof(readbuffer), &peeraddress)) > 0) @@ -1841,8 +1797,6 @@ void NetConn_ServerFrame(void) SV_DropClient(false); } } - for (conn = netconn_list;conn;conn = conn->next) - NetConn_ReSendMessage(conn); } void NetConn_QueryMasters(void) diff --git a/netconn.h b/netconn.h index 512b506d..85841309 100755 --- a/netconn.h +++ b/netconn.h @@ -126,7 +126,6 @@ typedef struct netconn_s double lastSendTime; qboolean canSend; - qboolean sendNext; // writing buffer to send to peer as the next reliable message // can be added to at any time, copied into sendMessage buffer when it is @@ -292,10 +291,6 @@ extern sizebuf_t net_message; extern cvar_t cl_netlocalping; -int NetConn_SendReliableMessage(netconn_t *conn, sizebuf_t *data); -//void NetConn_SendMessageNext(netconn_t *conn); -//void NetConn_ReSendMessage(netconn_t *conn); -qboolean NetConn_CanSendMessage(netconn_t *conn); int NetConn_SendUnreliableMessage(netconn_t *conn, sizebuf_t *data); void NetConn_CloseClientPorts(void); void NetConn_OpenClientPorts(void); @@ -310,9 +305,6 @@ netconn_t *NetConn_Open(lhnetsocket_t *mysocket, lhnetaddress_t *peeraddress); void NetConn_Close(netconn_t *conn); void NetConn_Listen(qboolean state); int NetConn_IsLocalGame(void); -//int NetConn_ReceivedMessage(netconn_t *conn, unsigned char *data, int length); -//int NetConn_ClientParsePacket(lhnetsocket_t *mysocket, unsigned char *data, int length, lhnetaddress_t *peeraddress); -//int NetConn_ServerParsePacket(lhnetsocket_t *mysocket, unsigned char *data, int length, lhnetaddress_t *peeraddress); void NetConn_ClientFrame(void); void NetConn_ServerFrame(void); void NetConn_QueryMasters(void); diff --git a/server.h b/server.h index 58e13ac5..0e9e3938 100644 --- a/server.h +++ b/server.h @@ -107,8 +107,6 @@ typedef struct client_s qboolean clientconnectcalled; // false = don't send datagrams qboolean spawned; - // only valid before spawned - qboolean sendsignon; // requested rate in bytes per second int rate; @@ -116,8 +114,8 @@ typedef struct client_s // realtime this client connected double connecttime; - // reliable messages must be sent periodically - double last_message; + // keepalive messages must be sent periodically during signon + double keepalivetime; // communications handle netconn_t *netconnection; diff --git a/sv_main.c b/sv_main.c index 57530854..92e12313 100644 --- a/sv_main.c +++ b/sv_main.c @@ -372,7 +372,6 @@ void SV_SendServerinfo (client_t *client) MSG_WriteByte (&client->netconnection->message, svc_signonnum); MSG_WriteByte (&client->netconnection->message, 1); - client->sendsignon = true; client->spawned = false; // need prespawn, spawn, etc } @@ -1180,7 +1179,7 @@ SV_SendClientDatagram ======================= */ static unsigned char sv_sendclientdatagram_buf[NET_MAXMESSAGE]; // FIXME? -qboolean SV_SendClientDatagram (client_t *client) +void SV_SendClientDatagram (client_t *client) { int rate, maxrate, maxsize, maxsize2; sizebuf_t msg; @@ -1219,31 +1218,35 @@ qboolean SV_SendClientDatagram (client_t *client) msg.maxsize = maxsize; msg.cursize = 0; - MSG_WriteByte (&msg, svc_time); - MSG_WriteFloat (&msg, sv.time); - - // add the client specific data to the datagram - SV_WriteClientdataToMessage (client, client->edict, &msg, stats); - VM_SV_WriteAutoSentStats (client, client->edict, &msg, stats); - SV_WriteEntitiesToClient (client, client->edict, &msg, stats); - - // expand packet size to allow effects to go over the rate limit - // (dropping them is FAR too ugly) - msg.maxsize = maxsize2; - - // copy the server datagram if there is space - // FIXME: put in delayed queue of effects to send - if (sv.datagram.cursize > 0 && msg.cursize + sv.datagram.cursize <= msg.maxsize) - SZ_Write (&msg, sv.datagram.data, sv.datagram.cursize); - -// send the datagram - if (NetConn_SendUnreliableMessage (client->netconnection, &msg) == -1) + if (host_client->spawned) { - SV_DropClient (true);// if the message couldn't send, kick off - return false; + MSG_WriteByte (&msg, svc_time); + MSG_WriteFloat (&msg, sv.time); + + // add the client specific data to the datagram + SV_WriteClientdataToMessage (client, client->edict, &msg, stats); + VM_SV_WriteAutoSentStats (client, client->edict, &msg, stats); + SV_WriteEntitiesToClient (client, client->edict, &msg, stats); + + // expand packet size to allow effects to go over the rate limit + // (dropping them is FAR too ugly) + msg.maxsize = maxsize2; + + // copy the server datagram if there is space + // FIXME: put in delayed queue of effects to send + if (sv.datagram.cursize > 0 && msg.cursize + sv.datagram.cursize <= msg.maxsize) + SZ_Write (&msg, sv.datagram.data, sv.datagram.cursize); + } + else if (realtime > client->keepalivetime) + { + // the player isn't totally in the game yet + // send small keepalive messages if too much time has passed + client->keepalivetime = realtime + 5; + MSG_WriteChar (&msg, svc_nop); } - return true; +// send the datagram + NetConn_SendUnreliableMessage (client->netconnection, &msg); } /* @@ -1337,30 +1340,6 @@ void SV_UpdateToReliableMessages (void) } -/* -======================= -SV_SendNop - -Send a nop message without trashing or sending the accumulated client -message buffer -======================= -*/ -void SV_SendNop (client_t *client) -{ - sizebuf_t msg; - unsigned char buf[4]; - - msg.data = buf; - msg.maxsize = sizeof(buf); - msg.cursize = 0; - - MSG_WriteChar (&msg, svc_nop); - - if (NetConn_SendUnreliableMessage (client->netconnection, &msg) == -1) - SV_DropClient (true); // if the message couldn't send, kick off - client->last_message = realtime; -} - /* ======================= SV_SendClientMessages @@ -1387,43 +1366,13 @@ void SV_SendClientMessages (void) continue; } - if (host_client->spawned) - { - if (!prepared) - { - prepared = true; - // only prepare entities once per frame - SV_PrepareEntitiesForSending(); - } - if (!SV_SendClientDatagram (host_client)) - continue; - } - else - { - // the player isn't totally in the game yet - // send small keepalive messages if too much time has passed - // send a full message when the next signon stage has been requested - // some other message data (name changes, etc) may accumulate - // between signon stages - if (!host_client->sendsignon) - { - if (realtime - host_client->last_message > 5) - SV_SendNop (host_client); - continue; // don't send out non-signon messages - } - } - - if (host_client->netconnection->message.cursize) + if (!prepared) { - if (!NetConn_CanSendMessage (host_client->netconnection)) - continue; - - if (NetConn_SendReliableMessage (host_client->netconnection, &host_client->netconnection->message) == -1) - SV_DropClient (true); // if the message couldn't send, kick off - SZ_Clear (&host_client->netconnection->message); - host_client->last_message = realtime; - host_client->sendsignon = false; + prepared = true; + // only prepare entities once per frame + SV_PrepareEntitiesForSending(); } + SV_SendClientDatagram (host_client); } // clear muzzle flashes