//----------------------------------------------------------------------------- // Name: SetVoiceOptions // Desc: Used by the UI to adjust voice through speakers and voice disable // voiceMode: 0 (disabled), 1 (speakers), 2 (enabled) //----------------------------------------------------------------------------- void CVoiceManager::SetVoiceOptions( int voiceMode ) { // Do nothing if we are banned - this might not be right if( logged_on && !XOnlineIsUserVoiceAllowed( XBLLoggedOnUsers[ IN_GetMainController() ].xuid.dwUserFlags ) ) return; // This should never happen, but... bool commPresent = CommunicatorPresent(); if( !commPresent && (voiceMode == 2) ) voiceMode = 1; // Store new settings: m_bVoiceDisabled = (voiceMode == 0); m_XHVVoiceManager.SetVoiceThroughSpeakers( (voiceMode == 1) ); // Update our friend notification: we have voice if not disabled, and we have a comm: if( logged_on ) XBL_F_SetState( XONLINE_FRIENDSTATE_FLAG_VOICE, (commPresent && !m_bVoiceDisabled) ); // Update our own player information, and inform other players if we're in a session if( m_bRunning ) { // We can receive voice as long as it's not disabled: if( !m_bVoiceDisabled ) xbOnlineInfo.xbPlayerList[xbOnlineInfo.localIndex].flags |= VOICE_CAN_RECV; else xbOnlineInfo.xbPlayerList[xbOnlineInfo.localIndex].flags &= ~VOICE_CAN_RECV; // We can send voice only if it's really enabled (implies that we have a comm): if( voiceMode == 2 ) xbOnlineInfo.xbPlayerList[xbOnlineInfo.localIndex].flags |= VOICE_CAN_SEND; else xbOnlineInfo.xbPlayerList[xbOnlineInfo.localIndex].flags &= ~VOICE_CAN_SEND; // Send our new state to everyone, if we have a communicator, we always // send HAVEVOICE, for TCR reasons: if( commPresent && !m_bVoiceDisabled ) SendVoiceInfo( VOICEINFO_HAVEVOICE, NULL ); else SendVoiceInfo( (VOICEINFO)voiceMode, NULL ); } }
//----------------------------------------------------------------------------- // Name: CommunicatorStatusUpdate // Desc: XHV Callback - called when the engine detects that the status of a // communicator has changed. May not be called if a communicator // is quickly removed and re-inserted, but in that case there is // nothing the game has to do. //----------------------------------------------------------------------------- HRESULT CVoiceManager::CommunicatorStatusUpdate( DWORD dwPort, XHV_VOICE_COMMUNICATOR_STATUS status ) { // If we're not initialized, then do nothing if( !m_bInitialized ) return S_OK; if( status == XHV_VOICE_COMMUNICATOR_STATUS_INSERTED ) { // Got a new headset: // Let the UI know that we have a headset, so it can enable things! Cvar_SetValue( "ui_headset", 1 ); // Awful UI hack. If we're on the online options screen, move off any item // that just became disabled. menuDef_t *menu = Menu_GetFocused(); if( menu && !Q_stricmp(menu->window.name, "xbl_onlineoptions") ) { VM_Call( uivm, UI_KEY_EVENT, A_CURSOR_DOWN, qtrue ); // Send a "move the cursor down" // Also, if we had "Speakers" selected, switch it to "Enabled" if( Cvar_VariableIntegerValue( "ui_voiceMode" ) == 1 ) Cvar_SetValue( "ui_voiceMode", 2 ); } // Always re-route voice to headset m_XHVVoiceManager.SetVoiceThroughSpeakers( FALSE ); // Don't do anything else if banned, or voice is disabled: if( m_bVoiceDisabled || (logged_on && !XOnlineIsUserVoiceAllowed( XBLLoggedOnUsers[ IN_GetMainController() ].xuid.dwUserFlags ) ) ) return S_OK; // If we're logged onto live, update our voice flag if( logged_on ) XBL_F_SetState( XONLINE_FRIENDSTATE_FLAG_VOICE, true ); // Finally, if we're in a session, update our status and tell everyone: if( m_bRunning ) { xbOnlineInfo.xbPlayerList[xbOnlineInfo.localIndex].flags |= VOICE_CAN_RECV; xbOnlineInfo.xbPlayerList[xbOnlineInfo.localIndex].flags |= VOICE_CAN_SEND; SendVoiceInfo( VOICEINFO_HAVEVOICE, NULL ); } } else if( status == XHV_VOICE_COMMUNICATOR_STATUS_REMOVED ) { // Lost a headset: // Let the UI know that we don't have a headset, so it can disable things! Cvar_SetValue( "ui_headset", 0 ); // Awful UI hack. If we're on the online options screen, move off any item // that just became disabled. menuDef_t *menu = Menu_GetFocused(); if( menu && !Q_stricmp(menu->window.name, "xbl_onlineoptions") ) { VM_Call( uivm, UI_KEY_EVENT, A_CURSOR_UP, qtrue ); // Send a "move the cursor up" // Also, if we had "Enabled" selected, that's no longer valid. Change ui_voiceMode: if( Cvar_VariableIntegerValue( "ui_voiceMode" ) == 2 ) Cvar_SetValue( "ui_voiceMode", 1 ); } // If the user pulls the headset and it was set to "speakers" or "enabled", // then change to "speakers" m_XHVVoiceManager.SetVoiceThroughSpeakers( !m_bVoiceDisabled ); // Don't do anything else if banned, or voice is disabled: if( m_bVoiceDisabled || (logged_on && !XOnlineIsUserVoiceAllowed( XBLLoggedOnUsers[ IN_GetMainController() ].xuid.dwUserFlags ) ) ) return S_OK; // If we're logged onto live, update our voice flag if( logged_on ) XBL_F_SetState( XONLINE_FRIENDSTATE_FLAG_VOICE, false ); // Finally, if we're in a session, update our status and tell everyone: if( m_bRunning ) { xbOnlineInfo.xbPlayerList[xbOnlineInfo.localIndex].flags |= VOICE_CAN_RECV; xbOnlineInfo.xbPlayerList[xbOnlineInfo.localIndex].flags &= ~VOICE_CAN_SEND; SendVoiceInfo( VOICEINFO_SPEAKERS, NULL ); } } return S_OK; }
void SV_SpawnServer( char *server, qboolean killBots, ForceReload_e eForceReload ) { int i; int checksum; qboolean isBot; char systemInfo[16384]; const char *p; SV_SendMapChange(); RE_RegisterMedia_LevelLoadBegin(server, eForceReload); // shut down the existing game if it is running SV_ShutdownGameProgs(); Com_Printf ("------ Server Initialization ------\n"); Com_Printf ("Server: %s\n",server); /* Ghoul2 Insert Start */ // de allocate the snapshot entities if (svs.snapshotEntities) { delete[] svs.snapshotEntities; svs.snapshotEntities = NULL; } /* Ghoul2 Insert End */ SV_SendMapChange(); #ifdef _XBOX // disable vsync during load for speed qglDisable(GL_VSYNC); #endif // if not running a dedicated server CL_MapLoading will connect the client to the server // also print some status stuff CL_MapLoading(); #ifndef DEDICATED // make sure all the client stuff is unloaded CL_ShutdownAll(); #endif CM_ClearMap(); #ifdef _XBOX R_DeleteTextures(); #endif // clear the whole hunk because we're (re)loading the server Hunk_Clear(); #ifdef _XBOX SV_ClearLastLevel(); ClientManager::ActivateClient(0); #endif R_InitSkins(); R_InitShaders(qtrue); // This was in SV_DedicatedSpawn, but it gets in the way of my memory maps: if( com_dedicated->integer ) { // Textures have been blown away - need to kill font system so it // will re-register shaders when UI re-scans menu files below: extern void R_ShutdownFonts( void ); R_ShutdownFonts(); } ClientManager::ClientActiveRelocate( !com_dedicated->integer && !ClientManager::splitScreenMode ); #if defined(_XBOX) && !defined(FINAL_BUILD) //Useful for memory debugging. Please don't delete. Comment out if //necessary. extern void Z_DisplayLevelMemory(int, int, int); extern void Z_Details_f(void); extern void Z_TagPointers(memtag_t); Z_DisplayLevelMemory(0, 0, 0); Z_TagPointers( TAG_ALL ); Z_Details_f(); #endif // init client structures and svs.numSnapshotEntities if ( !Cvar_VariableValue("sv_running") ) { SV_Startup(); } else { // check for maxclients change if ( sv_maxclients->modified ) { SV_ChangeMaxClients(); } } // Do dedicated server-specific startup if ( com_dedicated->integer ) { SV_DedicatedSpawn(server); } // Xbox - Correct various problems with broken rules settings when people // change gametype in-game, etc... SV_FixBrokenRules(); SV_SendMapChange(); /* Ghoul2 Insert Start */ // clear out those shaders, images and Models as long as this // isnt a dedicated server. /* if ( !com_dedicated->integer ) { #ifndef DEDICATED R_InitImages(); R_InitShaders(); R_ModelInit(); #endif } else */ if (com_dedicated->integer) { R_SVModelInit(); } SV_SendMapChange(); // clear pak references FS_ClearPakReferences(0); /* Ghoul2 Insert Start */ // allocate the snapshot entities on the hunk // svs.snapshotEntities = (struct entityState_s *)Hunk_Alloc( sizeof(entityState_t)*svs.numSnapshotEntities, h_high ); svs.nextSnapshotEntities = 0; // allocate the snapshot entities svs.snapshotEntities = new entityState_s[svs.numSnapshotEntities]; // we CAN afford to do this here, since we know the STL vectors in Ghoul2 are empty memset(svs.snapshotEntities, 0, sizeof(entityState_t)*svs.numSnapshotEntities); /* Ghoul2 Insert End */ // toggle the server bit so clients can detect that a // server has changed svs.snapFlagServerBit ^= SNAPFLAG_SERVERCOUNT; // set nextmap to the same map, but it may be overriden // by the game startup or another console command Cvar_Set( "nextmap", "map_restart 0"); // Cvar_Set( "nextmap", va("map %s", server) ); // wipe the entire per-level structure SV_ClearServer(); for ( i = 0 ; i < MAX_CONFIGSTRINGS ; i++ ) { sv.configstrings[i] = CopyString(""); } //rww - RAGDOLL_BEGIN G2API_SetTime(svs.time,0); //rww - RAGDOLL_END // make sure we are not paused Cvar_Set("cl_paused", "0"); // get a new checksum feed and restart the file system srand(Com_Milliseconds()); sv.checksumFeed = ( ((int) rand() << 16) ^ rand() ) ^ Com_Milliseconds(); FS_Restart( sv.checksumFeed ); #ifdef _XBOX CL_StartHunkUsers(); CM_LoadMap( va("maps/%s.bsp", server), qfalse, &checksum ); // RE_LoadWorldMap(va("maps/%s.bsp", server)); // Start up voice system if it isn't running yet. (ie, if we're on syslink) if( !logged_on ) g_Voice.Initialize(); #else CM_LoadMap( va("maps/%s.bsp", server), qfalse, &checksum ); #endif SV_SendMapChange(); // set serverinfo visible name Cvar_Set( "mapname", server ); Cvar_Set( "sv_mapChecksum", va("%i",checksum) ); // serverid should be different each time sv.serverId = com_frameTime; sv.restartedServerId = sv.serverId; Cvar_Set( "sv_serverid", va("%i", sv.serverId ) ); // clear physics interaction links SV_ClearWorld (); // media configstring setting should be done during // the loading stage, so connected clients don't have // to load during actual gameplay sv.state = SS_LOADING; // load and spawn all other entities SV_InitGameProgs(); // don't allow a map_restart if game is modified sv_gametype->modified = qfalse; // run a few frames to allow everything to settle for ( i = 0 ;i < 3 ; i++ ) { //rww - RAGDOLL_BEGIN G2API_SetTime(svs.time,0); //rww - RAGDOLL_END VM_Call( gvm, GAME_RUN_FRAME, svs.time ); SV_BotFrame( svs.time ); svs.time += 100; } //rww - RAGDOLL_BEGIN G2API_SetTime(svs.time,0); //rww - RAGDOLL_END // create a baseline for more efficient communications SV_CreateBaseline (); for (i=0 ; i<sv_maxclients->integer ; i++) { // send the new gamestate to all connected clients if (svs.clients[i].state >= CS_CONNECTED) { char *denied; if ( svs.clients[i].netchan.remoteAddress.type == NA_BOT ) { if ( killBots ) { SV_DropClient( &svs.clients[i], "" ); continue; } isBot = qtrue; } else { isBot = qfalse; } // connect the client again denied = (char *)VM_ExplicitArgPtr( gvm, VM_Call( gvm, GAME_CLIENT_CONNECT, i, qfalse, isBot ) ); // firstTime = qfalse if ( denied ) { // this generally shouldn't happen, because the client // was connected before the level change // SV_DropClient( &svs.clients[i], denied ); SV_DropClient( &svs.clients[i], "@MENUS_LOST_CONNECTION" ); } else { if( !isBot ) { // when we get the next packet from a connected client, // the new gamestate will be sent svs.clients[i].state = CS_CONNECTED; } else { client_t *client; sharedEntity_t *ent; client = &svs.clients[i]; client->state = CS_ACTIVE; ent = SV_GentityNum( i ); ent->s.number = i; client->gentity = ent; client->deltaMessage = -1; client->nextSnapshotTime = svs.time; // generate a snapshot immediately VM_Call( gvm, GAME_CLIENT_BEGIN, i ); } } } } // run another frame to allow things to look at all the players VM_Call( gvm, GAME_RUN_FRAME, svs.time ); SV_BotFrame( svs.time ); svs.time += 100; //rww - RAGDOLL_BEGIN G2API_SetTime(svs.time,0); //rww - RAGDOLL_END if ( sv_pure->integer ) { // the server sends these to the clients so they will only // load pk3s also loaded at the server p = FS_LoadedPakChecksums(); Cvar_Set( "sv_paks", p ); if (strlen(p) == 0) { Com_Printf( "WARNING: sv_pure set but no PK3 files loaded\n" ); } p = FS_LoadedPakNames(); Cvar_Set( "sv_pakNames", p ); // if a dedicated pure server we need to touch the cgame because it could be in a // seperate pk3 file and the client will need to load the latest cgame.qvm if ( com_dedicated->integer ) { SV_TouchCGame(); } } else { Cvar_Set( "sv_paks", "" ); Cvar_Set( "sv_pakNames", "" ); } // the server sends these to the clients so they can figure // out which pk3s should be auto-downloaded p = FS_ReferencedPakChecksums(); Cvar_Set( "sv_referencedPaks", p ); p = FS_ReferencedPakNames(); Cvar_Set( "sv_referencedPakNames", p ); // save systeminfo and serverinfo strings Q_strncpyz( systemInfo, Cvar_InfoString_Big( CVAR_SYSTEMINFO ), sizeof( systemInfo ) ); cvar_modifiedFlags &= ~CVAR_SYSTEMINFO; SV_SetConfigstring( CS_SYSTEMINFO, systemInfo ); SV_SetConfigstring( CS_SERVERINFO, Cvar_InfoString( CVAR_SERVERINFO ) ); cvar_modifiedFlags &= ~CVAR_SERVERINFO; // any media configstring setting now should issue a warning // and any configstring changes should be reliably transmitted // to all clients sv.state = SS_GAME; // send a heartbeat now so the master will get up to date info SV_Heartbeat_f(); Hunk_SetMark(); /* MrE: 2000-09-13: now called in CL_DownloadsComplete // don't call when running dedicated if ( !com_dedicated->integer ) { // note that this is called after setting the hunk mark with Hunk_SetMark CL_StartHunkUsers(); } */ // Xbox - Dedicated servers need to do extra work here. Most of this is done in // cl_parse normally, but that never runs in this case: if ( com_dedicated->integer ) { // Normally, we start advertising when we get the first snapshot. // Do it now. This is also necessary so that Net_GetXNKID works below. XBL_MM_Advertise(); // We need to put ourselves into the playerlist. xbOnlineInfo.localIndex = DEDICATED_SERVER_INDEX; XBPlayerInfo *plyrInfo = &xbOnlineInfo.xbPlayerList[DEDICATED_SERVER_INDEX]; memset( plyrInfo, 0, sizeof(XBPlayerInfo) ); // We get the first refIndex plyrInfo->refIndex = svs.clientRefNum++; // Address information plyrInfo->xbAddr = *Net_GetXNADDR( NULL ); XNetXnAddrToInAddr( &plyrInfo->xbAddr, Net_GetXNKID(), &plyrInfo->inAddr ); // Gamertag and XUID Q_strncpyz( plyrInfo->name, Cvar_VariableString("name"), sizeof(plyrInfo->name) ); XONLINE_USER *pUser; if (logged_on && (pUser = &XBLLoggedOnUsers[ IN_GetMainController() ]) && (pUser->hr == S_OK)) plyrInfo->xuid = pUser->xuid; else plyrInfo->xuid.qwUserID = plyrInfo->refIndex; plyrInfo->isActive = true; // Start up the voice chat session g_Voice.JoinSession(); // And mark ourselves as playing, so that others can join our game: XBL_F_SetState( XONLINE_FRIENDSTATE_FLAG_PLAYING, true ); } }