void fs2netd_do_frame() { // in a previous processing loop, so don't do a frame until that has completed if ( In_process ) { return; } if ( !Logged_in ) { // maybe try and reconnect, if we were bumped due to a comm error ... if ( (Login_retry_time != -1) && (timer_get_seconds() >= Login_retry_time) ) { fs2netd_login(); if ( !Logged_in ) { // bah! try again in another 5 minutes Login_retry_time = timer_get_seconds() + 300; } else { Login_retry_time = -1; } } return; } // do ping/pong and ident fs2netd_handle_ping(); if (!Is_connected) { // The ping handling above made us realize that we are disconnected. We will reconnect in some time so we can // just return here return; } // handle gameserver updates fs2netd_gameserver_update(); // check for server messages, ping replies, etc. fs2netd_handle_messages(); // WTF?! (TODO: figure out how this happens) if (Is_connected && !Logged_in) { fs2netd_login(); } }
// process an incoming multi options packet void multi_options_process_packet(unsigned char *data, header *hinfo) { ubyte code; multi_local_options bogus; int idx,player_index; char str[255]; int offset = HEADER_LENGTH; // find out who is sending this data player_index = find_player_id(hinfo->id); if (player_index < 0) { nprintf(("Network", "Received packet from unknown player!\n")); return; } // get the packet code GET_DATA(code); switch(code){ // get the start game options case MULTI_OPTION_START_GAME: Assert(Game_mode & GM_STANDALONE_SERVER); // get the netgame name GET_STRING(Netgame.name); // get the netgame mode GET_INT(Netgame.mode); // get the security # GET_INT(Netgame.security); // get mode specific data switch(Netgame.mode){ case NG_MODE_PASSWORD: GET_STRING(Netgame.passwd); break; case NG_MODE_RANK_ABOVE: case NG_MODE_RANK_BELOW: GET_INT(Netgame.rank_base); break; } // update standalone stuff std_connect_set_gamename(Netgame.name); std_multi_update_netgame_info_controls(); break; // get mission choice options case MULTI_OPTION_MISSION: netgame_info ng; char title[NAME_LENGTH+1]; int campaign_type,max_players; memset(&ng,0,sizeof(netgame_info)); Assert(Game_mode & GM_STANDALONE_SERVER); // coop or team vs. team mode GET_INT(ng.type_flags); if((ng.type_flags & NG_TYPE_TEAM) && !(Netgame.type_flags & NG_TYPE_TEAM)){ multi_team_reset(); } // if squad war was switched on if((ng.type_flags & NG_TYPE_SW) && !(Netgame.type_flags & NG_TYPE_SW)){ mprintf(("STANDALONE TURNED ON SQUAD WAR!!\n")); } Netgame.type_flags = ng.type_flags; // new respawn count GET_UINT(Netgame.respawn); // name string memset(str,0,255); GET_DATA(code); // campaign mode if(code){ GET_STRING(ng.campaign_name); // set the netgame max players here if the filename has changed if(strcmp(Netgame.campaign_name,ng.campaign_name) != 0){ memset(title,0,NAME_LENGTH+1); if(!mission_campaign_get_info(ng.campaign_name,title,&campaign_type,&max_players)){ Netgame.max_players = 0; } else { Netgame.max_players = max_players; } strcpy_s(Netgame.campaign_name,ng.campaign_name); } Netgame.campaign_mode = 1; // put brackets around the campaign name if(Game_mode & GM_STANDALONE_SERVER){ strcpy_s(str,"("); strcat_s(str,Netgame.campaign_name); strcat_s(str,")"); std_multi_set_standalone_mission_name(str); } } // non-campaign mode else { GET_STRING(ng.mission_name); if(strcmp(Netgame.mission_name,ng.mission_name) != 0){ if(strlen(ng.mission_name)){ Netgame.max_players = mission_parse_get_multi_mission_info( ng.mission_name ); } else { // setting this to -1 will prevent us from being seen on the network Netgame.max_players = -1; } strcpy_s(Netgame.mission_name,ng.mission_name); strcpy_s(Game_current_mission_filename,Netgame.mission_name); } Netgame.campaign_mode = 0; // set the mission name if(Game_mode & GM_STANDALONE_SERVER){ std_multi_set_standalone_mission_name(Netgame.mission_name); } } // update FS2NetD as well if (MULTI_IS_TRACKER_GAME) { fs2netd_gameserver_update(true); } send_netgame_update_packet(); break; // get the netgame options case MULTI_OPTION_SERVER: get_server_options(data, &offset, &Netgame.options); // if we're a standalone set for no sound, do so here if((Game_mode & GM_STANDALONE_SERVER) && !Multi_options_g.std_voice){ Netgame.options.flags |= MSO_FLAG_NO_VOICE; } else { // maybe update the quality of sound multi_voice_maybe_update_vars(Netgame.options.voice_qos,Netgame.options.voice_record_time); } // set the skill level Game_skill_level = Netgame.options.skill_level; if((Game_mode & GM_STANDALONE_SERVER) && !(Game_mode & GM_CAMPAIGN_MODE)){ Netgame.respawn = Netgame.options.respawn; } // if we have the "temp closed" flag toggle if(Netgame.options.flags & MLO_FLAG_TEMP_CLOSED){ Netgame.flags ^= NG_FLAG_TEMP_CLOSED; } Netgame.options.flags &= ~(MLO_FLAG_TEMP_CLOSED); // if i'm the standalone server, I should rebroadcast to all other players if(Game_mode & GM_STANDALONE_SERVER){ for(idx=0;idx<MAX_PLAYERS;idx++){ if(MULTI_CONNECTED(Net_players[idx]) && (Net_player != &Net_players[idx]) && (&Net_players[idx] != &Net_players[player_index]) ){ multi_io_send_reliable(&Net_players[idx], data, offset); } } send_netgame_update_packet(); } break; // local netplayer options case MULTI_OPTION_LOCAL: if(player_index == -1){ get_local_options(data, &offset, &bogus); } else { get_local_options(data, &offset, &Net_players[player_index].p_info.options); //If the client has sent an object update higher than that which the server allows, reset it if (Net_player->flags & NETINFO_FLAG_AM_MASTER) { if (Net_players[player_index].p_info.options.obj_update_level > Cmdline_objupd) { Net_players[player_index].p_info.options.obj_update_level = Cmdline_objupd; } } } break; } PACKET_SET_SIZE(); }