static void fs2netd_handle_ping() { static int CONN_check = -1; // if we didn't get a pong within 30 seconds of a ping then assume that the // server connection must of have dropped or is otherwise unresponsive if ( (Ping_timestamp != -1) && ((timer_get_seconds() - Ping_timestamp) > 30) ) { Ping_timestamp = -1; ml_string("FS2NetD WARNING: Lost connection to server!"); fs2netd_reset_connection(); // make sure that we are good to go if ( !Is_connected ) { if (!Is_standalone) { gamesnd_play_iface(SND_GENERAL_FAIL); popup(PF_USE_AFFIRMATIVE_ICON | PF_TITLE_BIG | PF_TITLE_RED, 1, POPUP_OK, "ERROR:\nLost connection to the FS2NetD server!"); } ml_string("FS2NetD ERROR: Lost connection to the FS2NetD server!"); fs2netd_disconnect(); ml_string("FS2NetD MSG: Will attempt an automatic reconnect to server in 5 minutes..."); Login_retry_time = timer_get_seconds() + 300; return; } else { ml_string("FS2NetD NOTICE: Connection to server has been reestablished!"); } } // send out a ping after 5 minutes of no other activity to make sure the server // is still responding (probably not though) if ( (Ping_timestamp == -1) && (timer_get_seconds() >= (Last_activity + 300)) ) { Ping_timestamp = timer_get_seconds(); FS2NetD_Ping(); ml_string("FS2NetD sent PING"); if (Last_activity < 0) { Last_activity = timer_get_seconds(); } } // check for a valid connection (SID, duplicate login, etc.) if ( (CONN_check == -1) || (timer_get_seconds() >= CONN_check) ) { // every 3 minutes CONN_check = timer_get_seconds() + 180; // session ID check if ( FS2NetD_CheckValidID() < 0 ) { ml_string("FS2NetD WARNING: Unable to validate login!"); fs2netd_reset_connection(); // make sure that we are good to go if ( !Is_connected ) { if (!Is_standalone) { gamesnd_play_iface(SND_GENERAL_FAIL); popup(PF_USE_AFFIRMATIVE_ICON | PF_TITLE_BIG | PF_TITLE_RED, 1, POPUP_OK, "ERROR:\nLost connection to the FS2NetD server!"); } ml_string("FS2NetD ERROR: Lost connection to the FS2NetD server!"); fs2netd_disconnect(); ml_string("FS2NetD MSG: Will attempt an automatic reconnect to server in 5 minutes..."); Login_retry_time = timer_get_seconds() + 300; return; } else { ml_string("FS2NetD NOTICE: Connection to server has been reestablished!"); } } // verify that we are only logged in once (for stats saving purposes) if ( (Netgame.game_state == NETGAME_STATE_BRIEFING) || (Netgame.game_state == NETGAME_STATE_MISSION_SYNC) ) { FS2NetD_CheckDuplicateLogin(); } ml_string("FS2NetD sent IDENT check"); } }
void fs2netd_do_frame() { int rc, buffer_size, buffer_offset; char buffer[300], str[256]; ubyte pid = 0; int itemp; static fix NextPing = -1, NextHeartBeat = -1; static fix GotPong = -1; bool reset = false; // don't bother with this if we aren't on FS2NetD if ( !Om_tracker_flag ) { return; } if ( !(Game_mode & GM_MULTIPLAYER) ) { return; } // not connected to server if ( !Is_connected ) { return; } // in a previous processing loop, so don't do a frame until that has completed if ( In_process ) { return; } // if we didn't get a PONG within 4 minutes the server connection must have dropped if ( (GotPong != -1) && ((NextPing - GotPong) > (240 * F1_0)) ) { ml_printf("FS2NetD WARNING: Lost connection to server!"); FS2NetD_Disconnect(); Is_connected = false; Logged_in = false; PXO_SID = -1; NextHeartBeat = -1; NextPing = -1; GotPong = -1; // try to reinit the server connection fs2netd_login(); // make sure that we are good to go if ( !Is_connected ) { if (!Is_standalone) { gamesnd_play_iface(SND_GENERAL_FAIL); popup(PF_USE_AFFIRMATIVE_ICON | PF_TITLE_BIG | PF_TITLE_RED, 1, POPUP_OK, "ERROR:\nLost connection to the FS2NetD server!"); } return; } else { ml_printf("FS2NetD NOTICE: Connection to server has been reestablished!"); } } // send out ping every 60 seconds if ( (NextPing == -1) || (timer_get_fixed_seconds() >= NextPing) ) { // if we have seen a long period of time between pings then reset the pong time too if ( (timer_get_fixed_seconds() - NextPing) > (120 * F1_0) ) { reset = true; } NextPing = timer_get_fixed_seconds() + (60 * F1_0); // we go ahead and set the initial GotPong here, even though we haven't gotten a pong yet if ( (GotPong == -1) || reset ) { GotPong = NextPing; reset = false; } FS2NetD_Ping(); ml_printf("FS2NetD sent PING"); } // send out server heartbeat every 2 minutes, unless forced to by an update if ( (Net_player->flags & NETINFO_FLAG_AM_MASTER) && (Multi_create_force_heartbeat || (NextHeartBeat == -1) || (timer_get_fixed_seconds() >= NextHeartBeat)) ) { Multi_create_force_heartbeat = 0; NextHeartBeat = timer_get_fixed_seconds() + (120 * F1_0); FS2NetD_SendHeartBeat(Netgame.name, Netgame.mission_name, Netgame.title, Netgame.type_flags, Netgame.server_addr.port, multi_num_players()); ml_printf("FS2NetD sent HeartBeat"); } // Check for GWall messages - ping replies, etc if ( (rc = FS2NetD_GetData(buffer, sizeof(buffer))) != -1 ) { int rc_total = rc; buffer_offset = 0; while (rc_total > buffer_offset) { // make sure we have enough data to try and process if (rc_total < BASE_PACKET_SIZE) { break; } PXO_GET_DATA( pid ); PXO_GET_INT( buffer_size ); while ( (rc_total < buffer_size) && ((sizeof(buffer) - rc_total) > 0) ) { if ( (rc = FS2NetD_GetData(buffer+rc_total, sizeof(buffer) - rc_total)) != -1 ) { rc_total += rc; } else { break; } } if (buffer_size <= 0) { break; } // we don't have the full packet, so bail if (rc_total < buffer_size) { break; } // processing time! switch (pid) { case PCKT_PING: { PXO_GET_INT( itemp ); ml_printf("FS2NetD received PING"); FS2NetD_Pong(itemp); break; } case PCKT_PONG: { PXO_GET_INT( itemp ); ml_printf("FS2NetD received PONG: %d ms", timer_get_milliseconds() - itemp); GotPong = timer_get_fixed_seconds(); break; } case PCKT_NETOWRK_WALL: { PXO_GET_STRING( str ); ml_printf("FS2NetD WALL received MSG: %s", str); switch (Netgame.game_state) { case NETGAME_STATE_FORMING: case NETGAME_STATE_BRIEFING: case NETGAME_STATE_MISSION_SYNC: case NETGAME_STATE_DEBRIEF: multi_display_chat_msg(str, 0, 0); break; /* -- Won't Happen - multi_do_frame() is not called during paused state so the game will not even receive the data during it case NETGAME_STATE_PAUSED: // EASY! send_game_chat_packet(Net_player, str, MULTI_MSG_ALL, NULL); break; */ case NETGAME_STATE_IN_MISSION: // gotta make it paused //multi_pause_request(1); //send_game_chat_packet(Net_player, str, MULTI_MSG_ALL, NULL); HUD_printf(str); break; default: // do-nothing break; } break; } default: { ml_printf("Unexpected FS2NetD Packet - PID = %x", pid); break; } } buffer_offset += (buffer_size - BASE_PACKET_SIZE); } } }