void fs2netd_options_config_init() { if ( !strlen(Multi_options_g.game_tracker_ip) ) { ml_printf("FS2NetD MSG: Address for game tracker not specified, using default instead (%s).", FS2NETD_DEFAULT_SERVER); strncpy( Multi_options_g.game_tracker_ip, FS2NETD_DEFAULT_SERVER, MULTI_OPTIONS_STRING_LEN ); } if ( !strlen(Multi_options_g.user_tracker_ip) ) { ml_printf("FS2NetD MSG: Address for user tracker not specified, using default instead (%s).", FS2NETD_DEFAULT_SERVER); strncpy( Multi_options_g.user_tracker_ip, FS2NETD_DEFAULT_SERVER, MULTI_OPTIONS_STRING_LEN ); } if ( !strlen(Multi_options_g.tracker_port) ) { ml_printf("FS2NetD MSG: Port for game/user trackers not specified, using default instead (%u).", FS2NETD_DEFAULT_PORT); strncpy( Multi_options_g.tracker_port, FS2NETD_DEFAULT_PORT, STD_NAME_LEN ); } if ( !strlen(Multi_options_g.pxo_ip) ) { ml_printf("FS2NetD MSG: Address for chat server not specified, using default instead (%s).", FS2NETD_DEFAULT_CHAT_SERVER); strncpy( Multi_options_g.pxo_ip, FS2NETD_DEFAULT_CHAT_SERVER, MULTI_OPTIONS_STRING_LEN ); } if ( !strlen(Multi_options_g.pxo_banner_url) ) { ml_printf("FS2NetD MSG: URL for banners not specified, using default instead (%s).", FS2NETD_DEFAULT_BANNER_URL); strncpy( Multi_options_g.pxo_banner_url, FS2NETD_DEFAULT_BANNER_URL, MULTI_OPTIONS_STRING_LEN ); } }
void fs2netd_connect() { int rc = 0; // don't bother with this if we aren't on FS2NetD if ( !Om_tracker_flag ) { return; } if ( !(Game_mode & GM_MULTIPLAYER) ) { return; } if (Is_connected) { return; } if ( !PXO_port ) { Assert( strlen(Multi_options_g.game_tracker_ip) ); Assert( strlen(Multi_options_g.tracker_port) ); if ( strlen(Multi_options_g.game_tracker_ip) ) { strncpy( PXO_Server, Multi_options_g.game_tracker_ip, sizeof(PXO_Server) - 1 ); } else { ml_printf("FS2NetD ERROR: No server specified in multi.cfg! Using default instead (%s)!", FS2NETD_DEFAULT_SERVER); strncpy( PXO_Server, FS2NETD_DEFAULT_SERVER, sizeof(PXO_Server) - 1 ); } if ( strlen(Multi_options_g.tracker_port) ) { long tmp = strtol(Multi_options_g.tracker_port, (char**)NULL, 10); if ( (tmp < 1024) || (tmp > USHRT_MAX) ) { ml_printf("FS2NetD ERROR: The port specified in multi.cfg, '%i', is outside of the required range, %i through %i!", tmp, 1024, USHRT_MAX); ml_printf("Fs2NetD ERROR: Setting port to default value (%s) ...", FS2NETD_DEFAULT_PORT); PXO_port = (ushort) strtol(FS2NETD_DEFAULT_PORT, (char**)NULL, 10); } else { PXO_port = (ushort)tmp; } } else { PXO_port = (ushort) strtol(FS2NETD_DEFAULT_PORT, (char**)NULL, 10); } } In_process = true; if (Is_standalone) { do { rc = fs2netd_connect_do(); } while (!rc); } else { popup_till_condition(fs2netd_connect_do, XSTR("&Cancel", 779), XSTR("Connecting into FS2NetD", -1)); } In_process = false; }
int fs2netd_get_pilot_info(const char *callsign, player *out_plr, bool first_call) { if ( !Logged_in ) { return -2; } if ( (out_plr == NULL) || (callsign == NULL) || !(strlen(callsign)) ) { return -2; } static player new_plr; if (first_call) { new_plr.reset(); strncpy( new_plr.callsign, callsign, CALLSIGN_LEN ); // initialize the stats to default values init_scoring_element( &new_plr.stats ); out_plr->reset(); Local_timeout = timer_get_seconds() + 30; In_process = true; ml_printf("FS2NetD MSG: Requesting pilot stats for '%s' ...", callsign); } int rc = FS2NetD_GetPlayerData(callsign, &new_plr, false, first_call); // some sort of failure if (rc > 0) { In_process = false; Local_timeout = -1; return -2; } // if timeout passes then bail on failure if ( timer_get_seconds() > Local_timeout ) { In_process = false; Local_timeout = -1; return -2; } if (rc == 0) { memcpy( out_plr, &new_plr, sizeof(player) ); In_process = false; Local_timeout = -1; } // we should only be returning -1 (processing) or 0 (got data successfully) return rc; }
// write out some info about stuff void multi_log_write_update() { int diff = (int)difftime(time(NULL), Multi_log_open_systime); int hours, mins, seconds; // figure out some time values hours = diff / 3600; mins = (diff - (hours * 3600)) / 60; seconds = (diff - (hours * 3600) - (mins * 60)); // print it out ml_printf("Server has been active for %d hours, %d minutes, and %d seconds", hours, mins, seconds); }
file_record* GetMissionsList(int &numMissions, const char *masterserver, UDP_Socket &Socket, int port, int timeout) { fs2open_file_check fc_packet; fc_packet.pid = PCKT_MISSIONS_RQST; timeout = timeout * CLK_TCK; int starttime = clock(); std::string sender = masterserver; // send Packet if (Socket.SendPacket((char *)&fc_packet, sizeof(fs2open_file_check), sender, port) == -1) return NULL; char PacketBuffer[16384]; // 16K should be enough i think..... I HOPE! fs2open_pxo_missreply *misreply_ptr = (fs2open_pxo_missreply *) PacketBuffer; file_record *frecs = NULL; numMissions = 0; while ((clock() - starttime) <= timeout) { if (Socket.GetPacket(PacketBuffer, 16384, sender) != -1) { if (misreply_ptr->pid != PCKT_MISSIONS_REPLY) { continue; // skip and ignore this packet } if ((misreply_ptr->num_files * sizeof(file_record)) + (sizeof(int) * 2) > 16384) { // WE'RE IN TROUBLE! ml_printf("Network (FS2OpenPXO): PCKT_MISSIONS_REPLY was larger than 16k!!!\n"); return NULL; } frecs = new file_record[misreply_ptr->num_files]; memcpy(frecs, PacketBuffer + 8, sizeof(file_record) * misreply_ptr->num_files); // packet buffer will be two ints then the array; numMissions = misreply_ptr->num_files; return frecs; } } return NULL; }
// setup kill matrix data void multi_df_setup_kill_matrix() { int idx, s_idx; multi_df_score *s; Multi_df_score_count = 0; // add players as necessary for(idx=0; idx<MAX_PLAYERS; idx++){ if(MULTI_CONNECTED(Net_players[idx]) && !MULTI_STANDALONE(Net_players[idx]) && !MULTI_PERM_OBSERVER(Net_players[idx]) && (Net_players[idx].m_player != NULL)){ // stuff data for this guy s = &Multi_df_score[Multi_df_score_count++]; ml_printf("Dogfight debrief stats for %s", Net_players[idx].m_player->callsign); for(s_idx=0; s_idx<MAX_PLAYERS; s_idx++){ ml_printf("%d", Net_players[idx].m_player->stats.m_dogfight_kills[s_idx]); } s->stats = Net_players[idx].m_player->stats; strcpy_s(s->callsign, Net_players[idx].m_player->callsign); s->np_index = idx; } } }
int fs2netd_get_valid_missions_do() { if (Local_timeout == -1) { Local_timeout = timer_get_seconds() + 30; } // get the available CRCs from the server if we need to if ( FS2NetD_file_list.empty() ) { int rc = FS2NetD_GetMissionsList(FS2NetD_file_list, do_full_packet); do_full_packet = false; // communications error if (rc < 0) { Local_timeout = -1; return 4; } // no missions if ( rc && FS2NetD_file_list.empty() ) { Local_timeout = -1; return 2; } // if timeout passes then bail on crc failure if ( timer_get_seconds() > Local_timeout ) { Local_timeout = -1; return 1; } } // we should have the CRCs, or there were no missions, so process them else { static char **file_names = NULL; static int idx = 0, count = 0; bool found = false; int file_index = 0; char valid_status = MVALID_STATUS_UNKNOWN; char full_name[MAX_FILENAME_LEN], wild_card[10]; char val_text[MAX_FILENAME_LEN+15]; uint checksum = 0; if (file_names == NULL) { // allocate filename space file_names = (char**) vm_malloc_q( sizeof(char*) * 1024 ); // 1024 files should be safe! if (file_names == NULL) { Local_timeout = -1; return 3; } memset( wild_card, 0, sizeof(wild_card) ); strcpy_s( wild_card, NOX("*") ); strcat_s( wild_card, FS_MISSION_FILE_EXT ); idx = count = cf_get_file_list(1024, file_names, CF_TYPE_MISSIONS, wild_card); } // drop idx first thing idx--; // we should be done validating, or just not have nothing to validate if (idx < 0) { for (idx = 0; idx < count; idx++) { if (file_names[idx] != NULL) { vm_free(file_names[idx]); file_names[idx] = NULL; } } vm_free(file_names); file_names = NULL; idx = count = 0; Local_timeout = -1; return 4; } // verify all filenames that we know about with their CRCs // NOTE: that this is done for one file per frame, since this is inside of a popup memset( full_name, 0, MAX_FILENAME_LEN ); strncpy( full_name, cf_add_ext(file_names[idx], FS_MISSION_FILE_EXT), sizeof(full_name) - 1 ); memset( val_text, 0, sizeof(val_text) ); snprintf( val_text, sizeof(val_text) - 1, "Validating: %s", full_name ); if (Is_standalone) { if ( std_gen_is_active() ) { std_gen_set_text(val_text, 1); } } else { popup_change_text(val_text); } cf_chksum_long(full_name, &checksum); // try and find the file file_index = multi_create_lookup_mission(full_name); found = false; if (file_index >= 0) { for (SCP_vector<file_record>::iterator fr = FS2NetD_file_list.begin(); fr != FS2NetD_file_list.end() && !found; ++fr) { if ( !stricmp(full_name, fr->name) ) { if (fr->crc32 == checksum) { found = true; valid_status = MVALID_STATUS_VALID; } else { valid_status = MVALID_STATUS_INVALID; } Multi_create_mission_list[file_index].valid_status = valid_status; } } if (found) { ml_printf("FS2NetD Mission Validation: %s => Valid!", full_name); } else { ml_printf("FS2NetD Mission Validation: %s => INVALID! -- 0x%08x", full_name, checksum); } } } return 0; }
static void fs2netd_handle_messages() { int buffer_size = 0, buffer_offset = 0; int bytes_read = 0; char tbuf[256]; char buffer[8192]; ubyte pid = 0; int itemp; while ( FS2NetD_DataReady() && (bytes_read < (int)sizeof(buffer)) ) { int read_size = FS2NetD_GetData(buffer+bytes_read, sizeof(buffer)-bytes_read); if (read_size <= 0) { break; } bytes_read += read_size; Sleep(20); } if ( (bytes_read == 0) || (bytes_read < BASE_PACKET_SIZE) ) { return; } Last_activity = timer_get_seconds(); buffer_offset = 0; while (buffer_offset+BASE_PACKET_SIZE <= bytes_read) { PXO_GET_DATA( pid ); PXO_GET_INT( buffer_size ); // packet has more data than our buffer received if (buffer_offset+buffer_size-BASE_PACKET_SIZE > bytes_read) { 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 PONG: %d ms", timer_get_milliseconds() - itemp); // reset timestamp, since the ping was successful Ping_timestamp = -1; break; } case PCKT_NETOWRK_WALL: { PXO_GET_STRING( tbuf ); ml_printf("FS2NetD WALL received MSG: %s", tbuf); 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(tbuf, 0, 0); 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(tbuf); break; default: // do-nothing break; } break; } case PCKT_CHAT_CHAN_COUNT_REPLY: { PXO_GET_STRING( tbuf ); PXO_GET_INT( itemp ); if ( (itemp < 0) || (itemp > USHRT_MAX) ) { itemp = 0; } multi_pxo_channel_count_update(tbuf, itemp); break; } case PCKT_VALID_SID_REPLY: { ubyte login_status = 0; PXO_GET_DATA( login_status ); if (login_status != 1) { ml_printf("FS2NetD IDENT: Got invalid login check!"); fs2netd_reset_connection(); } break; } case PCKT_DUP_LOGIN_REPLY: { ubyte dupe_status = 0; PXO_GET_DATA( dupe_status ); Duplicate_login_detected = (dupe_status != 0); break; } case PCKT_SLIST_REPLY: { int numServers = 0; int svr_flags; ushort svr_port; char svr_ip[16]; active_game ag; PXO_GET_USHORT( numServers ); if (numServers == 0) { break; } for (int i = 0; i < numServers; i++) { PXO_GET_INT( svr_flags ); PXO_GET_USHORT( svr_port ); PXO_GET_STRING( svr_ip ); if ( !psnet_is_valid_ip_string(svr_ip) ) { ml_printf("FS2NetD SLIST: Invalid ip string (%s)!", svr_ip); } else { memset( &ag, 0, sizeof(active_game) ); ag.server_addr.type = NET_TCP; ag.server_addr.port = (short) svr_port; if (ag.server_addr.port <= 0) { ag.server_addr.port = DEFAULT_GAME_PORT; } psnet_string_to_addr(&ag.server_addr, svr_ip); // query this server send_server_query(&ag.server_addr); } } break; } default: { break; } } } }
int fs2netd_login_do() { if (Multi_tracker_id < 0) { if ( Is_standalone && std_gen_is_active() ) { std_gen_set_text("Verifying username and password", 1); } else { popup_change_text( XSTR("Verifying username and password", 1576) ); } memset(Multi_tracker_id_string, 0, sizeof(Multi_tracker_id_string)); if (Local_timeout == -1) { Local_timeout = timer_get_seconds() + 15; } // if timeout passes then bail on SID failure if ( timer_get_seconds() > Local_timeout ) { ml_string("FS2NetD MSG: Login failure due to timeout!"); Local_timeout = -1; return 2; } const char *user = Multi_tracker_login; const char *passwd = Multi_tracker_passwd; if (Is_standalone) { if ( strlen(Multi_options_g.std_pxo_login) ) { user = Multi_options_g.std_pxo_login; } if ( strlen(Multi_options_g.std_pxo_password) ) { passwd = Multi_options_g.std_pxo_password; } } Multi_tracker_id = FS2NetD_Login(user, passwd, do_full_packet); // if we have already been through once then only deal with the recieve packet next time do_full_packet = false; // invalid login if (Multi_tracker_id == -2) { Multi_tracker_id = -1; Local_timeout = -1; return 1; } if (Multi_tracker_id >= 0) { ml_printf("FS2NetD MSG: Login '%s' is valid, session ID is %d!", user, Multi_tracker_id); do_full_packet = true; Local_timeout = -1; } } else { if ( Is_standalone && std_gen_is_active() ) { std_gen_set_text("Getting pilot stats", 1); } else { popup_change_text( XSTR("Getting pilot stats", 1577) ); } if (Local_timeout == -1) { Local_timeout = timer_get_seconds() + 30; } // if timeout passes then bail on stats failure if ( timer_get_seconds() > Local_timeout ) { Local_timeout = -1; return 2; } if (do_full_packet) { ml_printf("FS2NetD MSG: Requesting login pilot stats for '%s' ...", Players[Player_num].callsign); } int rescode = FS2NetD_GetPlayerData(Players[Player_num].callsign, &Players[Player_num], true, do_full_packet); do_full_packet = false; if ( rescode != -1 ) { Local_timeout = -1; return (rescode + 3); } } return 0; }
bool fs2netd_login() { bool retval = true; int rc; // don't bother with this if we aren't on FS2NetD if ( !Om_tracker_flag ) { return false; } if ( !(Game_mode & GM_MULTIPLAYER) ) { return false; } if ( Logged_in && (Multi_tracker_id >= 0) ) { return true; } Logged_in = false; Multi_tracker_id = -1; memset( Multi_tracker_id_string, 0, sizeof(Multi_tracker_id_string) ); // verify that our connection settings are sane fs2netd_options_config_init(); // if we're a standalone, show a dialog saying "validating tables" if (Is_standalone) { std_create_gen_dialog("Logging into FS2NetD"); std_gen_set_text("Connecting...", 1); } fs2netd_connect(); if ( !Is_connected ) { if ( !Is_standalone ) { popup(PF_USE_AFFIRMATIVE_ICON, 1, POPUP_OK, XSTR("Failed to connect to FS2NetD server!", 1578)); } else { std_gen_set_text("Connect FAILED!", 1); Sleep(2000); std_destroy_gen_dialog(); } return false; } char error_str[256]; char std_error_str[64]; do_full_packet = true; In_process = true; if (Is_standalone) { do { rc = fs2netd_login_do(); } while (!rc); } else { rc = popup_till_condition(fs2netd_login_do, XSTR("&Cancel", 779), XSTR("Logging into FS2NetD", 1579)); } In_process = false; Local_timeout = -1; memset( error_str, 0, sizeof(error_str) ); memset( std_error_str, 0, sizeof(std_error_str) ); switch (rc) { // the action was cancelled case 0: ml_string("FS2NetD MSG: Login process canceled by user."); retval = false; break; // didn't get a session id case 1: { const char *user = Multi_tracker_login; const char *passwd = Multi_tracker_passwd; if (Is_standalone) { if ( strlen(Multi_options_g.std_pxo_login) ) { user = Multi_options_g.std_pxo_login; } if ( strlen(Multi_options_g.std_pxo_password) ) { passwd = Multi_options_g.std_pxo_password; } } ml_printf("FS2NetD ERROR: Login %s/%s is invalid!", user, passwd); if (strlen(user) == 0) { strcpy_s(error_str, "Login failed! No username supplied. Go to options -> multi options and add one"); strcpy_s(std_error_str, "Login failed! No username!"); } else if (strlen(passwd) == 0) { strcpy_s(error_str, "Login failed! No password supplied. Go to options -> multi options and add one"); strcpy_s(std_error_str, "Login failed! No password!"); } else { strcpy_s(error_str, "Login failed!"); strcpy_s(std_error_str, "Login failed!"); } retval = false; break; } // unknown failure fetching pilot data case 2: ml_string("FS2NetD ERROR: UNKNOWN ERROR when fetching pilot data"); strcpy_s(error_str, "An Unknown Error (probably a timeout) occured when trying to retrieve your pilot data."); strcpy_s(std_error_str, "Unknown Error (timeout?)"); retval = false; break; // success!! case 3: ml_string("FS2NetD MSG: Got Pilot data"); retval = true; break; // success!! pilot was created case 4: ml_string("FS2NetD MSG: Created New Pilot"); strcpy_s(error_str, "New Pilot has been created."); strcpy_s(std_error_str, "New Pilot has been created."); retval = true; break; // invalid pilot name case 5: ml_string("FS2NetD ERROR: Invalid Pilot!"); strcpy_s(error_str, "Invalid pilot name - A serious error has occured, Contact the FS2NetD Administrator!"); strcpy_s(std_error_str, "Invalid pilot name!"); retval = false; break; // the session id was invalid case 6: ml_string("FS2NetD ERROR: Invalid SID!"); strcpy_s(error_str, "Invalid SID - A serious error has occured, Contact the FS2NetD Administrator!"); strcpy_s(std_error_str, "Invalid SID"); retval = false; break; default: ml_string("FS2NetD ERROR: Unknown return case for GetPlayerData()"); strcpy_s(error_str, "Unknown return case from GetPlayerData(). Contact the FS2NetD Administrator!"); retval = false; break; } if ( !Is_standalone && strlen(error_str) ) { popup(PF_USE_AFFIRMATIVE_ICON, 1, POPUP_OK, error_str); } else if ( Is_standalone && std_gen_is_active() && strlen(std_error_str) ) { std_gen_set_text(std_error_str, 1); Sleep(2000); } if (retval) { Logged_in = true; sprintf(Multi_tracker_id_string, "%d", Multi_tracker_id); } else { // clear and reset connection, for the next time we try... fs2netd_disconnect(); } if (Is_standalone) { std_destroy_gen_dialog(); } return retval; }
int FS2NetD_GetMissionsList(SCP_vector<file_record> &m_list, bool do_send) { int buffer_size, buffer_offset; bool my_packet = false; char buffer[16384]; if (do_send) { INIT_PACKET( PCKT_MISSIONS_RQST ); DONE_PACKET(); if ( FS2NetD_SendData(buffer, buffer_size) == -1 ) { return -1; } } else if ( FS2NetD_DataReady() ) { const fix end_time = timer_get_fixed_seconds() + (15 * F1_0); int rc; uint rc_total = 0; int i, num_files = 0; file_record nrec; do { rc = FS2NetD_GetData(buffer+rc_total, sizeof(buffer)-rc_total); if (rc <= 0) { break; } rc_total += rc; Sleep(20); } while ( FS2NetD_DataReady() && (rc_total < (int)sizeof(buffer)) ); if (rc < BASE_PACKET_SIZE) { return 0; } VRFY_PACKET2( PCKT_MISSIONS_REPLY ); if ( !my_packet ) { return 0; } if ( buffer_size > (int)sizeof(buffer) ) { ml_printf("FS2NetD WARNING: Mission list data is larger than receive buffer! Some data will be lost!"); } // make sure that we get the entire packet while ( (rc_total < (uint)buffer_size) && (rc_total < sizeof(buffer)) && (timer_get_fixed_seconds() <= end_time) ) { if ( FS2NetD_DataReady() ) { rc = FS2NetD_GetData(buffer+rc_total, sizeof(buffer) - rc_total); if (rc <= 0) { continue; } rc_total += rc; } Sleep(20); } PXO_GET_INT( num_files ); for (i = 0; i < num_files; i++) { memset(&nrec, 0, sizeof(file_record)); PXO_GET_STRING( nrec.name ); PXO_GET_UINT( nrec.crc32 ); m_list.push_back( nrec ); } return 1; } return 0; }
int fs2netd_update_valid_tables() { int rc; int hacked = 0; // if there are no tables to check with then bail if ( Table_valid_status.empty() ) { return -1; } // if we're not on FS2NetD then don't bother with this function if ( !Om_tracker_flag && (Game_mode & GM_MULTIPLAYER) ) { return -1; } // maybe try to init first fs2netd_connect(); // if we didn't connect to FS2NetD then bail out now if ( !Is_connected ) { return -1; } // if we're a standalone, show a dialog saying "validating tables" if (Game_mode & GM_STANDALONE_SERVER) { std_create_gen_dialog("Validating tables"); std_gen_set_text("Querying FS2NetD:", 1); } do_full_packet = 1; In_process = true; if (Is_standalone) { do { rc = fs2netd_update_valid_tables_do(); } while (!rc); } else { rc = popup_till_condition(fs2netd_update_valid_tables_do, XSTR("&Cancel", 779), XSTR("Starting table validation", -1)); } In_process = false; switch (rc) { // canceled by popup case 0: return -1; // timed out case 1: { if ( !Is_standalone ) { popup(PF_USE_AFFIRMATIVE_ICON, 1, POPUP_OK, XSTR("Table validation timed out!", -1)); } return -1; } // no tables case 2: { if ( !Is_standalone ) { popup(PF_USE_AFFIRMATIVE_ICON, 1, POPUP_OK, XSTR("No tables are available from the server for validation!", -1)); } return -1; } } // output the status of table validity to multi.log for (uint i = 0; i < Table_valid_status.size(); i++) { if (Table_valid_status[i].valid) { ml_printf("FS2NetD Table Check: '%s' -- Valid!", Table_valid_status[i].name); } else { ml_printf("FS2NetD Table Check: '%s' -- INVALID (0x%x)!", Table_valid_status[i].name, Table_valid_status[i].crc32); hacked = 1; } } // if we're a standalone, kill the validate dialog if (Game_mode & GM_STANDALONE_SERVER) { std_destroy_gen_dialog(); } return hacked; }
int FS2NetD_GetPlayerData(const char *player_name, player *pl, bool can_create, bool do_send) { int buffer_size, buffer_offset; bool my_packet = false; char buffer[16384]; if (do_send) { ubyte create = (ubyte)can_create; INIT_PACKET( PCKT_PILOT_GET ); PXO_ADD_INT( (can_create) ? Multi_tracker_id : -2 ); PXO_ADD_STRING( player_name ); PXO_ADD_DATA( create ); DONE_PACKET(); if ( FS2NetD_SendData(buffer, buffer_size) == -1 ) { return -1; } } else if ( FS2NetD_DataReady() ) { const fix end_time = timer_get_fixed_seconds() + (15 * F1_0); int rc; uint rc_total = 0; ubyte reply_type = 0; int si_index = 0; ushort bogus, num_type_kills = 0, num_medals = 0; char ship_name[NAME_LENGTH]; int idx; do { rc = FS2NetD_GetData(buffer+rc_total, sizeof(buffer)-rc_total); if (rc <= 0) { break; } rc_total += rc; Sleep(20); } while ( FS2NetD_DataReady() && (rc_total < (int)sizeof(buffer)) ); if (rc < BASE_PACKET_SIZE) { return -1; } VRFY_PACKET2( PCKT_PILOT_REPLY ); if ( !my_packet ) { return -1; } if ( buffer_size > (int)sizeof(buffer) ) { ml_printf("FS2NetD WARNING: Pilot update data is larger than receive buffer! Some data will be lost!"); } // make sure that we get the entire packet while ( (rc_total < (uint)buffer_size) && (rc_total < sizeof(buffer)) && (timer_get_fixed_seconds() <= end_time) ) { if ( FS2NetD_DataReady() ) { rc = FS2NetD_GetData(buffer+rc_total, sizeof(buffer) - rc_total); if (rc <= 0) { continue; } rc_total += rc; } Sleep(20); } PXO_GET_DATA( reply_type ); // if we weren't retrieved then bail out now if (reply_type != 0) { return (int)reply_type; } PXO_GET_INT( pl->stats.score ); // points PXO_GET_UINT( pl->stats.missions_flown ); // missions PXO_GET_UINT( pl->stats.flight_time ); // flighttime PXO_GET_INT( pl->stats.last_flown ); // LastFlight PXO_GET_INT( pl->stats.kill_count ); // Kills PXO_GET_INT( pl->stats.kill_count_ok ); // NonFriendlyKills PXO_GET_INT( pl->stats.assists ); // Assists PXO_GET_UINT( pl->stats.p_shots_fired ); // PriShots PXO_GET_UINT( pl->stats.p_shots_hit ); // PriHits PXO_GET_UINT( pl->stats.p_bonehead_hits ); // PriFHits PXO_GET_UINT( pl->stats.s_shots_fired ); // SecShots PXO_GET_UINT( pl->stats.s_shots_hit ); // SecHits PXO_GET_UINT( pl->stats.s_bonehead_hits ); // SecFHits PXO_GET_INT( pl->stats.rank ); // rank PXO_GET_USHORT( num_type_kills ); for (idx = 0; idx < (int)num_type_kills; idx++) { memset( ship_name, 0, sizeof(ship_name) ); PXO_GET_STRING( ship_name ); si_index = ship_info_lookup( ship_name ); if (si_index == -1) { PXO_GET_USHORT( bogus ); } else { PXO_GET_USHORT( pl->stats.kills[si_index] ); } } PXO_GET_USHORT( num_medals ); for (idx = 0; (idx < Num_medals) && (idx < num_medals); idx++) { PXO_GET_INT( pl->stats.medal_counts[idx] ); } return (int)reply_type; } return -1; }
void fs2netd_options_config_init() { if (PXO_options_loaded) { return; } if ( !strlen(Multi_options_g.game_tracker_ip) ) { ml_printf("NOTICE: Address for game tracker not specified, using default instead (%s).", FS2NETD_DEFAULT_SERVER); strncpy( Multi_options_g.game_tracker_ip, FS2NETD_DEFAULT_SERVER, MULTI_OPTIONS_STRING_LEN ); } else if ( !strcmp("gt.pxo.net", Multi_options_g.game_tracker_ip) ) { ml_printf("NOTICE: Incompatible game tracker IP detected (gt.pxo.net), using default instead (%s)!", FS2NETD_DEFAULT_SERVER); strncpy( Multi_options_g.game_tracker_ip, FS2NETD_DEFAULT_SERVER, MULTI_OPTIONS_STRING_LEN ); } if ( !strlen(Multi_options_g.user_tracker_ip) ) { ml_printf("NOTICE: Address for user tracker not specified, using default instead (%s).", FS2NETD_DEFAULT_SERVER); strncpy( Multi_options_g.user_tracker_ip, FS2NETD_DEFAULT_SERVER, MULTI_OPTIONS_STRING_LEN ); } else if ( !strcmp("ut.pxo.net", Multi_options_g.user_tracker_ip) ) { ml_printf("NOTICE: Incompatible user tracker IP detected (ut.pxo.net), using default instead (%s)!", FS2NETD_DEFAULT_SERVER); strncpy( Multi_options_g.user_tracker_ip, FS2NETD_DEFAULT_SERVER, MULTI_OPTIONS_STRING_LEN ); } if ( !strlen(Multi_options_g.tracker_port) ) { ml_printf("NOTICE: Port for game/user trackers not specified, using default instead (%s).", FS2NETD_DEFAULT_PORT); strncpy( Multi_options_g.tracker_port, FS2NETD_DEFAULT_PORT, STD_NAME_LEN ); } else { long port_tmp = strtol(Multi_options_g.tracker_port, (char**)NULL, 10); if ( (port_tmp < 1024) || (port_tmp > USHRT_MAX) ) { ml_printf("NOTICE: The port specified for game/user trackers, '%i', is outside of the required range, %i through %i!", port_tmp, 1024, USHRT_MAX); ml_printf("NOTICE: Port for game/user trackers is invalid, using default instead (%s).", FS2NETD_DEFAULT_PORT); strncpy( Multi_options_g.tracker_port, FS2NETD_DEFAULT_PORT, STD_NAME_LEN ); } } if ( !strlen(Multi_options_g.pxo_ip) ) { ml_printf("NOTICE: Address for chat server not specified, using default instead (%s).", FS2NETD_DEFAULT_CHAT_SERVER); strncpy( Multi_options_g.pxo_ip, FS2NETD_DEFAULT_CHAT_SERVER, MULTI_OPTIONS_STRING_LEN ); } else if ( !strcmp("chat.pxo.net", Multi_options_g.pxo_ip) ) { ml_printf("NOTICE: Incompatible chat server IP detected (chat.pxo.net), using default instead (%s)!", FS2NETD_DEFAULT_CHAT_SERVER); strncpy( Multi_options_g.pxo_ip, FS2NETD_DEFAULT_CHAT_SERVER, MULTI_OPTIONS_STRING_LEN ); } if ( !strlen(Multi_options_g.pxo_banner_url) ) { ml_printf("NOTICE: URL for banners not specified, using default instead (%s).", FS2NETD_DEFAULT_BANNER_URL); strncpy( Multi_options_g.pxo_banner_url, FS2NETD_DEFAULT_BANNER_URL, MULTI_OPTIONS_STRING_LEN ); } else if ( !strcmp("http://www.pxo.net/files/banners", Multi_options_g.pxo_banner_url) ) { ml_printf("NOTICE: Incompatible banner URL detected (chat.pxo.net), using default instead (%s)!", FS2NETD_DEFAULT_BANNER_URL); strncpy( Multi_options_g.pxo_banner_url, FS2NETD_DEFAULT_BANNER_URL, MULTI_OPTIONS_STRING_LEN ); } PXO_options_loaded = true; }
int fs2netd_login_do() { if (PXO_SID == -1) { if ( Is_standalone && std_gen_is_active() ) { std_gen_set_text("Verifying username and password", 1); } else { popup_change_text( XSTR("Verifying username and password", -1) ); } if (timeout == -1) { timeout = timer_get_fixed_seconds() + (15 * F1_0); } // if timeout passes then bail on SID failure if ( timer_get_fixed_seconds() > timeout ) { timeout = -1; return 2; } PXO_SID = FS2NetD_Login(Multi_tracker_login, Multi_tracker_passwd, do_full_packet); // if we have already been through once then only deal with the recieve packet next time do_full_packet = 0; // invalid login if (PXO_SID == -2) { timeout = -1; return 1; } if (PXO_SID >= 0) { ml_printf("FS2NetD MSG: Login %s is valid, session ID is %i!", Multi_tracker_login, PXO_SID); do_full_packet = 1; timeout = -1; } } else { if ( Is_standalone && std_gen_is_active() ) { std_gen_set_text("Getting pilot stats", 1); } else { popup_change_text( XSTR("Getting pilot stats", -1) ); } if (timeout == -1) { timeout = timer_get_fixed_seconds() + (30 * F1_0); } // if timeout passes then bail on stats failure if ( timer_get_fixed_seconds() > timeout ) { timeout = -1; return 2; } int rescode = FS2NetD_GetPlayerData(PXO_SID, Players[Player_num].callsign, &Players[Player_num], true, do_full_packet); do_full_packet = 0; if ( rescode != -1 ) { timeout = -1; return (rescode + 3); } } return 0; }
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); } } }
bool fs2netd_login() { bool retval = true; int rc; // don't bother with this if we aren't on FS2NetD if ( !Om_tracker_flag ) { return false; } if ( !(Game_mode & GM_MULTIPLAYER) ) { return false; } if ( Logged_in ) { if ( (PXO_SID != -1) && !(FS2NetD_CheckValidSID(PXO_SID)) ) { PXO_SID = -1; } else { return true; } } fs2netd_connect(); if ( !Is_connected ) { if ( !Is_standalone ) { popup(PF_USE_AFFIRMATIVE_ICON, 1, POPUP_OK, XSTR("Failed to connect to FS2NetD server!", -1)); } return false; } char error_str[256]; do_full_packet = 1; In_process = true; if (Is_standalone) { do { rc = fs2netd_login_do(); } while (!rc); } else { rc = popup_till_condition(fs2netd_login_do, XSTR("&Cancel", 779), XSTR("Logging into FS2NetD", -1)); } In_process = false; memset( error_str, 0, sizeof(error_str) ); switch (rc) { // the action was cancelled case 0: retval = false; break; // didn't get a session id case 1: ml_printf("FS2NetD ERROR: Login %s/%s is invalid!", Multi_tracker_login, Multi_tracker_passwd); strcpy(error_str, "Login failed!"); retval = false; break; // unknown failure fetching pilot data case 2: ml_printf("FS2NetD ERROR: UNKNOWN ERROR when fetching pilot data"); strcpy(error_str, "An Unknown Error (probably a timeout) occured when trying to retrieve your pilot data."); retval = false; break; // success!! case 3: ml_printf("FS2NetD MSG: Got Pilot data"); retval = true; break; // success!! pilot was created case 4: ml_printf("FS2NetD MSG: Created New Pilot"); strcpy(error_str, "New Pilot has been created."); retval = true; break; // invalid pilot name case 5: ml_printf("FS2NetD ERROR: Invalid Pilot!"); strcpy(error_str, "Invalid Pilot name - A serious error has occured, Contact the FS2NetD Administrator!"); retval = false; break; // the session id was invalid case 6: ml_printf("FS2NetD ERROR: Invalid SID!"); strcpy(error_str, "Invalid SID - A serious error has occured, Contact the FS2NetD Administrator!"); retval = false; break; default: ml_printf("FS2NetD ERROR: Unknown return case for GetPlayerData()"); strcpy(error_str, "Unkown return case from GetPlayerData(). Contact the FS2NetD Administrator!"); retval = false; break; } if ( !Is_standalone && strlen(error_str) ) { popup(PF_USE_AFFIRMATIVE_ICON, 1, POPUP_OK, error_str); } if (retval) { Logged_in = true; } return retval; }
int FS2NetD_GetBanList(SCP_vector<SCP_string> &mask_list, bool do_send) { int buffer_size, buffer_offset; bool my_packet = false; char buffer[16384]; if (do_send) { INIT_PACKET( PCKT_BANLIST_RQST ); DONE_PACKET(); if ( FS2NetD_SendData(buffer, buffer_size) == -1 ) { return -1; } } else if ( FS2NetD_DataReady() ) { const fix end_time = timer_get_fixed_seconds() + (15 * F1_0); int rc; uint rc_total = 0; int num_files = 0; char ip_mask[32]; int idx; do { rc = FS2NetD_GetData(buffer+rc_total, sizeof(buffer)-rc_total); if (rc <= 0) { break; } rc_total += rc; Sleep(20); } while ( FS2NetD_DataReady() && (rc_total < (int)sizeof(buffer)) ); if (rc < BASE_PACKET_SIZE) { return -1; } VRFY_PACKET2( PCKT_BANLIST_RPLY ); if ( !my_packet ) { return 0; } if ( buffer_size > (int)sizeof(buffer) ) { ml_printf("FS2NetD WARNING: Banned user list data is larger than receive buffer! Some data will be lost!"); } // make sure that we get the entire packet while ( (rc_total < (uint)buffer_size) && (rc_total < sizeof(buffer)) && (timer_get_fixed_seconds() <= end_time) ) { if ( FS2NetD_DataReady() ) { rc = FS2NetD_GetData(buffer+rc_total, sizeof(buffer) - rc_total); if (rc <= 0) { continue; } rc_total += rc; } Sleep(20); } PXO_GET_INT( num_files ); for (idx = 0; idx < num_files; idx++) { PXO_GET_STRING( ip_mask ); mask_list.push_back( ip_mask ); } return 1; } return 0; }
int fs2netd_update_valid_tables() { int rc; int hacked = 0; if ( !Logged_in ) { return -1; } // if there are no tables to check with then bail if ( Table_valid_status.empty() ) { return -1; } // if we're a standalone, show a dialog saying "validating tables" if (Game_mode & GM_STANDALONE_SERVER) { std_create_gen_dialog("Validating tables"); std_gen_set_text("Querying FS2NetD:", 1); } do_full_packet = true; In_process = true; if (Is_standalone) { do { rc = fs2netd_update_valid_tables_do(); } while (!rc); } else { rc = popup_till_condition(fs2netd_update_valid_tables_do, XSTR("&Cancel", 779), XSTR("Starting table validation", 1592)); } In_process = false; Local_timeout = -1; switch (rc) { // canceled by popup case 0: return -1; // timed out case 1: { if ( !Is_standalone ) { popup(PF_USE_AFFIRMATIVE_ICON, 1, POPUP_OK, XSTR("Table validation timed out!", 1593)); } return -1; } // no tables case 2: { if ( !Is_standalone ) { popup(PF_USE_AFFIRMATIVE_ICON, 1, POPUP_OK, XSTR("No tables are available from the server for validation!", 1594)); } return -1; } } // output the status of table validity to multi.log for (SCP_vector<crc_valid_status>::iterator tvs = Table_valid_status.begin(); tvs != Table_valid_status.end(); ++tvs) { if (tvs->valid) { ml_printf("FS2NetD Table Check: '%s' -- Valid!", tvs->name); } else { ml_printf("FS2NetD Table Check: '%s' -- INVALID (0x%x)!", tvs->name, tvs->crc32); hacked = 1; } } // if we're a standalone, kill the validate dialog if (Game_mode & GM_STANDALONE_SERVER) { std_destroy_gen_dialog(); } return hacked; }
int FS2NetD_ValidateTableList(bool do_send) { int buffer_size, buffer_offset; bool my_packet = false; char buffer[4096]; ushort num_tables = 0; if (do_send) { // create and send the request packet INIT_PACKET( PCKT_TABLES_RQST ); num_tables = (ushort)Table_valid_status.size(); PXO_ADD_USHORT( num_tables ); for (SCP_vector<crc_valid_status>::iterator tvs = Table_valid_status.begin(); tvs != Table_valid_status.end(); ++tvs) { PXO_ADD_STRING(tvs->name ); PXO_ADD_UINT( tvs->crc32 ); } DONE_PACKET(); if (FS2NetD_SendData(buffer, buffer_size) == -1) { return -1; } } else if ( FS2NetD_DataReady() ) { int rc; const fix end_time = timer_get_fixed_seconds() + (15 * F1_0); ubyte tbl_valid_status = 0; uint rc_total = 0; do { rc = FS2NetD_GetData(buffer+rc_total, sizeof(buffer)-rc_total); if (rc <= 0) { break; } rc_total += rc; Sleep(20); } while ( FS2NetD_DataReady() && (rc_total < (int)sizeof(buffer)) ); if (rc < BASE_PACKET_SIZE) { return -1; } VRFY_PACKET2( PCKT_TABLES_REPLY ); if ( !my_packet ) { return -1; } // make sure that we get the entire packet while ( (rc_total < (uint)buffer_size) && (rc_total < sizeof(buffer)) && (timer_get_fixed_seconds() <= end_time) ) { if ( FS2NetD_DataReady() ) { rc = FS2NetD_GetData(buffer+rc_total, sizeof(buffer) - rc_total); if (rc <= 0) { continue; } rc_total += rc; } Sleep(20); } PXO_GET_USHORT( num_tables ); if ( !num_tables ) { return -1; } if ( num_tables > (int)Table_valid_status.size() ) { ml_printf("FS2NetD WARNING: Table list contains %i tables, but we only requested %i! Invalid data!", num_tables, Table_valid_status.size()); return -1; } for (SCP_vector<crc_valid_status>::iterator tvs = Table_valid_status.begin(); tvs != Table_valid_status.end(); ++tvs) { PXO_GET_DATA( tbl_valid_status ); Assert( (tbl_valid_status == 0) || (tbl_valid_status == 1) ); tvs->valid = tbl_valid_status; } return 2; } return 0; }
void fs2netd_options_config_init() { if (PXO_options_loaded) { return; } if ( !strlen(Multi_options_g.game_tracker_ip) ) { ml_printf("NOTICE: Address for game tracker not specified, using default instead (%s).", FS2NETD_DEFAULT_SERVER); strncpy( Multi_options_g.game_tracker_ip, FS2NETD_DEFAULT_SERVER, MULTI_OPTIONS_STRING_LEN ); } else if ( !strcmp("gt.pxo.net", Multi_options_g.game_tracker_ip) ) { ml_printf("NOTICE: Incompatible game tracker IP detected (gt.pxo.net), using default instead (%s)!", FS2NETD_DEFAULT_SERVER); strncpy( Multi_options_g.game_tracker_ip, FS2NETD_DEFAULT_SERVER, MULTI_OPTIONS_STRING_LEN ); } if ( !strlen(Multi_options_g.user_tracker_ip) ) { ml_printf("NOTICE: Address for user tracker not specified, using default instead (%s).", FS2NETD_DEFAULT_SERVER); strncpy( Multi_options_g.user_tracker_ip, FS2NETD_DEFAULT_SERVER, MULTI_OPTIONS_STRING_LEN ); } else if ( !strcmp("ut.pxo.net", Multi_options_g.user_tracker_ip) ) { ml_printf("NOTICE: Incompatible user tracker IP detected (ut.pxo.net), using default instead (%s)!", FS2NETD_DEFAULT_SERVER); strncpy( Multi_options_g.user_tracker_ip, FS2NETD_DEFAULT_SERVER, MULTI_OPTIONS_STRING_LEN ); } if ( !strlen(Multi_options_g.tracker_port) ) { if ( FS2NetD_port >= 1024 && FS2NetD_port <= USHRT_MAX ) { ml_printf("NOTICE: User override for game/user tracker port not specified, using game_settings.tbl override (%i).", FS2NetD_port); int result; result = sprintf(Multi_options_g.tracker_port, "%i", FS2NetD_port); Assertion( result > 0, "Copying port %i to tracker_port failed\n", FS2NetD_port ); } else { if ( FS2NetD_port != 0 ) { ml_printf("ERROR: game_settings.tbl override for game/user tracker port '%i' must be between %i and %i.", FS2NetD_port, 1024, USHRT_MAX); } ml_printf("NOTICE: Port for game/user trackers not specified, using default instead (%s).", FS2NETD_DEFAULT_PORT); strncpy( Multi_options_g.tracker_port, FS2NETD_DEFAULT_PORT, STD_NAME_LEN ); } } else { long port_tmp = strtol(Multi_options_g.tracker_port, (char**)NULL, 10); if ( (port_tmp < 1024) || (port_tmp > USHRT_MAX) ) { ml_printf("NOTICE: The port specified for game/user trackers, '%ld', is outside of the required range, %i through %i!", port_tmp, 1024, USHRT_MAX); ml_printf("NOTICE: Port for game/user trackers is invalid, using default instead (%s).", FS2NETD_DEFAULT_PORT); strncpy( Multi_options_g.tracker_port, FS2NETD_DEFAULT_PORT, STD_NAME_LEN ); } } if ( !strlen(Multi_options_g.pxo_ip) ) { ml_printf("NOTICE: Address for chat server not specified, using default instead (%s).", FS2NETD_DEFAULT_CHAT_SERVER); strncpy( Multi_options_g.pxo_ip, FS2NETD_DEFAULT_CHAT_SERVER, MULTI_OPTIONS_STRING_LEN ); } else if ( !strcmp("chat.pxo.net", Multi_options_g.pxo_ip) ) { ml_printf("NOTICE: Incompatible chat server IP detected (chat.pxo.net), using default instead (%s)!", FS2NETD_DEFAULT_CHAT_SERVER); strncpy( Multi_options_g.pxo_ip, FS2NETD_DEFAULT_CHAT_SERVER, MULTI_OPTIONS_STRING_LEN ); } if ( !strlen(Multi_options_g.pxo_banner_url) ) { ml_printf("NOTICE: URL for banners not specified, using default instead (%s).", FS2NETD_DEFAULT_BANNER_URL); strncpy( Multi_options_g.pxo_banner_url, FS2NETD_DEFAULT_BANNER_URL, MULTI_OPTIONS_STRING_LEN ); } else if ( !strcmp("http://www.pxo.net/files/banners", Multi_options_g.pxo_banner_url) ) { ml_printf("NOTICE: Incompatible banner URL detected (chat.pxo.net), using default instead (%s)!", FS2NETD_DEFAULT_BANNER_URL); strncpy( Multi_options_g.pxo_banner_url, FS2NETD_DEFAULT_BANNER_URL, MULTI_OPTIONS_STRING_LEN ); } PXO_options_loaded = true; }