static void UpdateMasterServer(void) { unsigned int now; now = I_GetTimeMS(); // The address of the master server can change. Periodically // re-resolve the master server to update. if (now - master_resolve_time > MASTER_RESOLVE_PERIOD * 1000) { net_addr_t *new_addr; printf("Re-resolve master server\n"); new_addr = NET_Query_ResolveMaster(server_context); // Has the master server changed address? if (new_addr != NULL && new_addr != master_server) { NET_FreeAddress(master_server); master_server = new_addr; } master_resolve_time = now; } // Possibly refresh our registration with the master server. if (now - master_refresh_time > MASTER_REFRESH_PERIOD * 1000) { NET_Query_AddToMaster(master_server); master_refresh_time = now; } }
static void NET_CL_Shutdown(void) { if (net_client_connected) { net_client_connected = false; NET_FreeAddress(server_addr); // Shut down network module, etc. To do. } }
void NET_CL_Run(void) { net_addr_t *addr; net_packet_t *packet; if (!net_client_connected) { return; } while (NET_RecvPacket(client_context, &addr, &packet)) { // only accept packets from the server if (addr == server_addr) { NET_CL_ParsePacket(packet); } else { NET_FreeAddress(addr); } NET_FreePacket(packet); } // Run the common connection code to send any packets as needed NET_Conn_Run(&client_connection); if (client_connection.state == NET_CONN_STATE_DISCONNECTED || client_connection.state == NET_CONN_STATE_DISCONNECTED_SLEEP) { NET_CL_Disconnected(); NET_CL_Shutdown(); } net_waiting_for_launch = client_connection.state == NET_CONN_STATE_CONNECTED && client_state == CLIENT_STATE_WAITING_LAUNCH; if (client_state == CLIENT_STATE_IN_GAME) { // Possibly advance the receive window NET_CL_AdvanceWindow(); // Check if our resend requests have timed out NET_CL_CheckResends(); } }
static void NET_SV_RunClient(net_client_t *client) { // Run common code NET_Conn_Run(&client->connection); if (client->connection.state == NET_CONN_STATE_DISCONNECTED && client->connection.disconnect_reason == NET_DISCONNECT_TIMEOUT) { NET_SV_BroadcastMessage("Client '%s' timed out and disconnected", client->name); } // Is this client disconnected? if (client->connection.state == NET_CONN_STATE_DISCONNECTED) { // deactivate and free back client->active = false; free(client->name); NET_FreeAddress(client->addr); // Are there any clients left connected? If not, return the // server to the waiting-for-players state. // // Disconnect any drones still connected. if (NET_SV_NumPlayers() <= 0) { NET_SV_GameEnded(); } } if (!ClientConnected(client)) { // client has not yet finished connecting return; } if (server_state == SERVER_WAITING_START) { // Waiting for the game to start // Send information once every second if (client->last_send_time < 0 || I_GetTimeMS() - client->last_send_time > 1000) { NET_SV_SendWaitingData(client); client->last_send_time = I_GetTimeMS(); } } if (server_state == SERVER_IN_GAME) { NET_SV_PumpSendQueue(client); NET_SV_CheckDeadlock(client); } }
static void NET_SV_Packet(net_packet_t *packet, net_addr_t *addr) { net_client_t *client; unsigned int packet_type; // Response from master server? if (addr != NULL && addr == master_server) { NET_Query_MasterResponse(packet); return; } // Find which client this packet came from client = NET_SV_FindClient(addr); // Read the packet type if (!NET_ReadInt16(packet, &packet_type)) { // no packet type return; } if (packet_type == NET_PACKET_TYPE_SYN) { NET_SV_ParseSYN(packet, client, addr); } else if (packet_type == NET_PACKET_TYPE_QUERY) { NET_SV_SendQueryResponse(addr); } else if (client == NULL) { // Must come from a valid client; ignore otherwise } else if (NET_Conn_Packet(&client->connection, packet, &packet_type)) { // Packet was eaten by the common connection code } else { //printf("SV: %s: %i\n", NET_AddrToString(addr), packet_type); switch (packet_type) { case NET_PACKET_TYPE_GAMESTART: NET_SV_ParseGameStart(packet, client); break; case NET_PACKET_TYPE_GAMEDATA: NET_SV_ParseGameData(packet, client); break; case NET_PACKET_TYPE_GAMEDATA_ACK: NET_SV_ParseGameDataACK(packet, client); break; case NET_PACKET_TYPE_GAMEDATA_RESEND: NET_SV_ParseResendRequest(packet, client); break; default: // unknown packet type break; } } // If this address is not in the list of clients, be sure to // free it back. if (NET_SV_FindClient(addr) == NULL) { NET_FreeAddress(addr); } }