// process a player kick packet void process_player_kick_packet(ubyte *data, header *hinfo) { int player_num,from_player,ban,reason; short player_id; int offset = HEADER_LENGTH; // get the address of the guy who is to be kicked GET_SHORT(player_id); GET_INT(ban); GET_INT(reason); player_num = find_player_id(player_id); PACKET_SET_SIZE(); // only the server should ever receive a request to kick a guy Assert(Net_player->flags & NETINFO_FLAG_AM_MASTER); // determine who sent the packet from_player = find_player_id(hinfo->id); // check to see if this guy is allowed to make such a request if((from_player == -1) || !multi_kick_can_kick(&Net_players[from_player]) ){ nprintf(("Network","Received a kick request from an invalid player!!\n")); } // otherwise, process the request fully else { // make sure we have a valid player to kick if(player_num == -1){ nprintf(("Network","Received request to kick an unknown player!\n")); } else { // will handle all the rest of the details multi_kick_player(player_num,ban,reason); } } }
// process incoming squadmate messaging info void multi_msg_process_squadmsg_packet(unsigned char *data, header *hinfo) { int command; ushort net_sig; short source_id; int source_index; char s_val; int offset = HEADER_LENGTH; // get all packet data GET_INT(command); GET_SHORT(source_id); GET_USHORT(net_sig); GET_DATA(s_val); PACKET_SET_SIZE(); // determine who the order is from source_index = find_player_id(source_id); if(source_index == -1){ nprintf(("Network","Received squadmsg order packet from unknown player!!\n")); return; } // display the squadmessage somehow multi_msg_show_squadmsg(&Net_players[source_index],command,net_sig,(int)s_val); }
// process an incoming respawn info packet void multi_respawn_process_packet(ubyte *data, header *hinfo) { ubyte code,cur_link_status; char cur_primary_bank,cur_secondary_bank; ushort net_sig,ship_ets; short player_id; int player_index; vector v; char parse_name[1024] = ""; int offset = HEADER_LENGTH; // determine who send the packet player_index = find_player_id(hinfo->id); if(player_index == -1){ nprintf(("Network","Couldn't find player for processing respawn packet!\n")); } // get the opcode GET_DATA(code); // do something based upon the opcode switch((int)code){ case AI_RESPAWN_NOTICE: p_object *pobjp; GET_USHORT( net_sig ); pobjp = mission_parse_get_arrival_ship( net_sig ); Assert( pobjp != NULL ); multi_respawn_ai( pobjp ); break; case RESPAWN_BROADCAST: // get the respawn data GET_USHORT(net_sig); get_vector_data( data, &offset, v ); GET_SHORT(player_id); GET_DATA(cur_primary_bank); GET_DATA(cur_secondary_bank); GET_DATA(cur_link_status); GET_USHORT(ship_ets); GET_STRING(parse_name); player_index = find_player_id(player_id); if(player_index == -1){ nprintf(("Network","Couldn't find player to respawn!\n")); break; } // create the ship and assign its position, net_signature, and class // respawn the player multi_respawn_player(&Net_players[player_index], cur_primary_bank, cur_secondary_bank, cur_link_status, ship_ets, net_sig, parse_name, &v); // if this is for me, I should jump back into gameplay if(&Net_players[player_index] == Net_player){ extern int Player_multi_died_check; Player_multi_died_check = -1; gameseq_post_event(GS_EVENT_ENTER_GAME); } break; case RESPAWN_REQUEST: // determine whether he wants to respawn as an observer or not GET_DATA(code); nprintf(("Network","Received respawn request\n")); if(player_index == -1){ nprintf(("Network","Received respawn request from unknown player!\n")); break; } // make sure he's not making an invalid request if((code == 0) && !(Net_players[player_index].flags & NETINFO_FLAG_RESPAWNING)){ nprintf(("Network","Received respawn request from player who shouldn't be respawning!\n")); Int3(); break; } else if((code == 1) && !(Net_players[player_index].flags & NETINFO_FLAG_LIMBO)){ nprintf(("Network","Received respawn observer request from a player who shouldn't be respawning as an observer!\n")); Int3(); break; } // otherwise perform the operation // respawn the guy as an observer if(code){ multi_respawn_make_observer(&Net_players[player_index]); } // respawn him as normal else { // create his new ship, and change him from respawning to respawned Assert(Net_players[player_index].p_info.p_objp != NULL); if(Net_players[player_index].p_info.p_objp != NULL){ multi_respawn_player(&Net_players[player_index], Net_players[player_index].s_info.cur_primary_bank, Net_players[player_index].s_info.cur_secondary_bank,Net_players[player_index].s_info.cur_link_status, Net_players[player_index].s_info.ship_ets, 0, Net_players[player_index].p_info.p_objp->name); } } break; } PACKET_SET_SIZE(); }
// 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(); }