diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/d_net.h | 7 | ||||
-rw-r--r-- | src/net_client.c | 32 | ||||
-rw-r--r-- | src/net_defs.h | 8 | ||||
-rw-r--r-- | src/net_server.c | 103 |
4 files changed, 146 insertions, 4 deletions
diff --git a/src/d_net.h b/src/d_net.h index 2b293dac..07f4e59a 100644 --- a/src/d_net.h +++ b/src/d_net.h @@ -1,7 +1,7 @@ // Emacs style mode select -*- C++ -*- //----------------------------------------------------------------------------- // -// $Id: d_net.h 18 2005-07-23 18:56:07Z fraggle $ +// $Id: d_net.h 323 2006-01-22 22:29:42Z fraggle $ // // Copyright(C) 1993-1996 Id Software, Inc. // Copyright(C) 2005 Simon Howard @@ -131,6 +131,7 @@ typedef struct } doomcom_t; +extern int extratics; // Create any new ticcmds and broadcast to other players. void NetUpdate (void); @@ -148,6 +149,10 @@ void TryRunTics (void); //----------------------------------------------------------------------------- // // $Log$ +// Revision 1.4 2006/01/22 22:29:42 fraggle +// Periodically request the time from clients to estimate their offset to +// the server time. +// // Revision 1.3 2005/07/23 18:56:07 fraggle // Remove unneccessary pragmas // diff --git a/src/net_client.c b/src/net_client.c index ed24c239..b1f14c20 100644 --- a/src/net_client.c +++ b/src/net_client.c @@ -1,7 +1,7 @@ // Emacs style mode select -*- C++ -*- //----------------------------------------------------------------------------- // -// $Id: net_client.c 312 2006-01-21 14:16:49Z fraggle $ +// $Id: net_client.c 323 2006-01-22 22:29:42Z fraggle $ // // Copyright(C) 2005 Simon Howard // @@ -21,6 +21,10 @@ // 02111-1307, USA. // // $Log$ +// Revision 1.23 2006/01/22 22:29:42 fraggle +// Periodically request the time from clients to estimate their offset to +// the server time. +// // Revision 1.22 2006/01/21 14:16:49 fraggle // Add first game data sending code. Check the client version when connecting. // @@ -373,6 +377,28 @@ static void NET_CL_ParseGameStart(net_packet_t *packet) autostart = true; } +static void NET_CL_ParseTimeRequest(net_packet_t *packet) +{ + net_packet_t *reply; + unsigned int seq; + + // Received a request from the server for our current time. + + if (!NET_ReadInt32(packet, &seq)) + { + return; + } + + // Send a response with our current time. + + reply = NET_NewPacket(10); + NET_WriteInt16(reply, NET_PACKET_TYPE_TIME_RESP); + NET_WriteInt32(reply, seq); + NET_WriteInt32(reply, I_GetTimeMS()); + NET_Conn_SendPacket(&client_connection, reply); + NET_FreePacket(reply); +} + // parse a received packet static void NET_CL_ParsePacket(net_packet_t *packet) @@ -403,6 +429,10 @@ static void NET_CL_ParsePacket(net_packet_t *packet) case NET_PACKET_TYPE_GAMEDATA: break; + case NET_PACKET_TYPE_TIME_REQ: + NET_CL_ParseTimeRequest(packet); + break; + default: break; } diff --git a/src/net_defs.h b/src/net_defs.h index 310bb4ec..906ad91a 100644 --- a/src/net_defs.h +++ b/src/net_defs.h @@ -1,7 +1,7 @@ // Emacs style mode select -*- C++ -*- //----------------------------------------------------------------------------- // -// $Id: net_defs.h 312 2006-01-21 14:16:49Z fraggle $ +// $Id: net_defs.h 323 2006-01-22 22:29:42Z fraggle $ // // Copyright(C) 2005 Simon Howard // @@ -21,6 +21,10 @@ // 02111-1307, USA. // // $Log$ +// Revision 1.11 2006/01/22 22:29:42 fraggle +// Periodically request the time from clients to estimate their offset to +// the server time. +// // Revision 1.10 2006/01/21 14:16:49 fraggle // Add first game data sending code. Check the client version when connecting. // @@ -148,6 +152,8 @@ typedef enum NET_PACKET_TYPE_DISCONNECT, NET_PACKET_TYPE_DISCONNECT_ACK, NET_PACKET_TYPE_RELIABLE_ACK, + NET_PACKET_TYPE_TIME_REQ, + NET_PACKET_TYPE_TIME_RESP, } net_packet_type_t; typedef struct diff --git a/src/net_server.c b/src/net_server.c index a84c53a2..b9a15594 100644 --- a/src/net_server.c +++ b/src/net_server.c @@ -1,7 +1,7 @@ // Emacs style mode select -*- C++ -*- //----------------------------------------------------------------------------- // -// $Id: net_server.c 312 2006-01-21 14:16:49Z fraggle $ +// $Id: net_server.c 323 2006-01-22 22:29:42Z fraggle $ // // Copyright(C) 2005 Simon Howard // @@ -21,6 +21,10 @@ // 02111-1307, USA. // // $Log$ +// Revision 1.23 2006/01/22 22:29:42 fraggle +// Periodically request the time from clients to estimate their offset to +// the server time. +// // Revision 1.22 2006/01/21 14:16:49 fraggle // Add first game data sending code. Check the client version when connecting. // @@ -141,6 +145,12 @@ typedef struct net_connection_t connection; int last_send_time; char *name; + + // time query variables + + int last_time_req_time; + int time_req_seq; + signed int time_offset; } net_client_t; static net_server_state_t server_state; @@ -401,6 +411,9 @@ static void NET_SV_ParseSYN(net_packet_t *packet, client->addr = addr; client->last_send_time = -1; client->name = strdup(player_name); + client->last_time_req_time = -1; + client->time_req_seq = 0; + client->time_offset = 0; } if (client->connection.state == NET_CONN_STATE_WAITING_ACK) @@ -460,6 +473,60 @@ static void NET_SV_ParseGameStart(net_packet_t *packet, net_client_t *client) } } +static void NET_SV_ParseTimeResponse(net_packet_t *packet, net_client_t *client) +{ + unsigned int seq; + unsigned int remote_time; + unsigned int rtt; + unsigned int nowtime; + signed int time_offset; + + if (!NET_ReadInt32(packet, &seq) + || !NET_ReadInt32(packet, &remote_time)) + { + return; + } + + if (seq != client->time_req_seq) + { + // Not the time response we are expecting + + return; + } + + // Calculate the round trip time + + nowtime = I_GetTimeMS(); + rtt = nowtime - client->last_time_req_time; + + // Adjust the remote time based on the round trip time + + remote_time += rtt / 2; + + // Calculate the offset to our own time + + time_offset = remote_time - nowtime; + + // Update the time offset + + if (client->time_req_seq == 1) + { + // This is the first reply, so this is the only sample we have + // so far + + client->time_offset = time_offset; + } + else + { + // Apply a low level filter to the time offset adjustments + + client->time_offset = ((client->time_offset * 3) / 4) + + (time_offset / 4); + } + + printf("client %p time offset: %i(%i)->%i\n", client, time_offset, rtt, client->time_offset); +} + // Process a packet received by the server static void NET_SV_Packet(net_packet_t *packet, net_addr_t *addr) @@ -501,6 +568,9 @@ static void NET_SV_Packet(net_packet_t *packet, net_addr_t *addr) case NET_PACKET_TYPE_GAMESTART: NET_SV_ParseGameStart(packet, client); break; + case NET_PACKET_TYPE_TIME_RESP: + NET_SV_ParseTimeResponse(packet, client); + break; default: // unknown packet type @@ -566,6 +636,25 @@ static void NET_SV_SendWaitingData(net_client_t *client) NET_FreePacket(packet); } +static void NET_SV_SendTimeRequest(net_client_t *client) +{ + net_packet_t *packet; + + ++client->time_req_seq; + + // Transmit the request packet + + packet = NET_NewPacket(10); + NET_WriteInt16(packet, NET_PACKET_TYPE_TIME_REQ); + NET_WriteInt32(packet, client->time_req_seq); + NET_Conn_SendPacket(&client->connection, packet); + NET_FreePacket(packet); + + // Save the time we send the request + + client->last_time_req_time = I_GetTimeMS(); +} + // Perform any needed action on a client static void NET_SV_RunClient(net_client_t *client) @@ -605,6 +694,18 @@ static void NET_SV_RunClient(net_client_t *client) client->last_send_time = I_GetTimeMS(); } } + + if (client->last_time_req_time < 0) + { + client->last_time_req_time = I_GetTimeMS() - 5000; + } + + if (I_GetTimeMS() - client->last_time_req_time > 10000) + { + // Query the clients' times once every ten seconds. + + NET_SV_SendTimeRequest(client); + } } // Initialise server and wait for connections |