/* =========================================================================== Doom 3 BFG Edition GPL Source Code Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company. This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code"). Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Doom 3 BFG Edition Source Code. If not, see . In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below. If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA. =========================================================================== */ #pragma hdrstop #include "../idlib/precompiled.h" idCVar com_requireNonProductionSignIn( "com_requireNonProductionSignIn", "1", CVAR_BOOL|CVAR_ARCHIVE, "If true, will require sign in, even on non production builds." ); extern idCVar fs_savepath; extern idCVar g_demoMode; /* ======================== idSignInManagerBase::ProcessInputEvent ======================== */ bool idSignInManagerBase::ProcessInputEvent( const sysEvent_t * ev ) { // If we could use more local users, poll for them if ( GetNumLocalUsers() < maxDesiredLocalUsers && !IsAnyDeviceBeingRegistered() ) { if ( ev->IsKeyDown() ) { if ( ev->GetKey() == K_JOY1 || ev->GetKey() == K_JOY9 || ev->GetKey() == K_ENTER || ev->GetKey() == K_KP_ENTER ) { // Register a local user so they can use this input device only done for demos press start screen // otherwise the user is registered when selecting which game to play. } } } return false; } /* ======================== idSignInManagerBase::GetDefaultProfile ======================== */ idPlayerProfile * idSignInManagerBase::GetDefaultProfile() { if ( defaultProfile == NULL ) { // Create a new profile defaultProfile = idPlayerProfile::CreatePlayerProfile( 0 ); } return defaultProfile; } /* ======================== idSignInManagerBase::GetLocalUserByInputDevice ======================== */ idLocalUser * idSignInManagerBase::GetLocalUserByInputDevice( int index ) { for ( int i = 0; i < GetNumLocalUsers(); i++ ) { if ( GetLocalUserByIndex( i )->GetInputDevice() == index ) { return GetLocalUserByIndex( i ); // Found it } } return NULL; // Not found } /* ======================== idSignInManagerBase::GetLocalUserByHandle ======================== */ idLocalUser * idSignInManagerBase::GetLocalUserByHandle( localUserHandle_t handle ) { for ( int i = 0; i < GetNumLocalUsers(); i++ ) { if ( GetLocalUserByIndex( i )->GetLocalUserHandle() == handle ) { return GetLocalUserByIndex( i ); // Found it } } return NULL; // Not found } /* ======================== idSignInManagerBase::GetPlayerProfileByInputDevice ======================== */ idPlayerProfile * idSignInManagerBase::GetPlayerProfileByInputDevice( int index ) { idLocalUser * user = session->GetSignInManager().GetLocalUserByInputDevice( index ); idPlayerProfile * profile = NULL; if ( user != NULL ) { profile = user->GetProfile(); } return profile; } /* ======================== idSignInManagerBase::RemoveLocalUserByInputDevice ======================== */ bool idSignInManagerBase::RemoveLocalUserByInputDevice( int index ) { for ( int i = 0; i < GetNumLocalUsers(); i++ ) { if ( GetLocalUserByIndex( i )->GetInputDevice() == index ) { RemoveLocalUserByIndex( i ); return true; } } return false; // Not found } /* ======================== idSignInManagerBase::RemoveLocalUserByHandle ======================== */ bool idSignInManagerBase::RemoveLocalUserByHandle( localUserHandle_t handle ) { for ( int i = 0; i < GetNumLocalUsers(); i++ ) { if ( GetLocalUserByIndex( i )->GetLocalUserHandle() == handle ) { RemoveLocalUserByIndex( i ); return true; } } return false; // Not found } /* ======================== idSignInManagerBase::SaveUserProfiles ======================== */ void idSignInManagerBase::SaveUserProfiles() { for ( int i = 0; i < GetNumLocalUsers(); i++ ) { idLocalUser * localUser = GetLocalUserByIndex( i ); if ( localUser != NULL ) { idPlayerProfile * profile = localUser->GetProfile(); if ( profile != NULL ) { profile->SaveSettings( false ); } } } } /* ======================== idSignInManagerBase::RemoveAllLocalUsers ======================== */ void idSignInManagerBase::RemoveAllLocalUsers() { while ( GetNumLocalUsers() > 0 ) { RemoveLocalUserByIndex( 0 ); } } /* ======================== idSignInManagerBase::ValidateLocalUsers ======================== */ void idSignInManagerBase::ValidateLocalUsers( bool requireOnline ) { if ( !RequirePersistentMaster() ) { return; } for ( int i = GetNumLocalUsers() - 1; i >= 0; i-- ) { idLocalUser * localUser = GetLocalUserByIndex( i ); // If this user does not have a profile, remove them. // If this user is not online-capable and we require online, remove them. if ( !localUser->IsProfileReady() || ( requireOnline && ( !localUser->IsOnline() || !localUser->CanPlayOnline() ) ) ) { RemoveLocalUserByIndex( i ); } } } /* ======================== idSignInManagerBase::RequirePersistentMaster ======================== */ bool idSignInManagerBase::RequirePersistentMaster() { #ifdef ID_RETAIL return true; // ALWAYS require persistent master on retail builds #else // Non retail production builds require a persistent profile unless si_splitscreen is set extern idCVar si_splitscreen; // If we are forcing splitscreen, then we won't require a profile (this is for development) if ( si_splitscreen.GetInteger() != 0 ) { return false; } return com_requireNonProductionSignIn.GetBool(); #endif } /* ======================== idSignInManagerBase::GetUniqueLocalUserHandle Uniquely generate a handle based on name and time ======================== */ localUserHandle_t idSignInManagerBase::GetUniqueLocalUserHandle( const char * name ) { MD5_CTX ctx; unsigned char digest[16]; int64 clockTicks = Sys_GetClockTicks(); MD5_Init( &ctx ); MD5_Update( &ctx, (const unsigned char *)name, idStr::Length( name ) ); MD5_Update( &ctx, (const unsigned char *)&clockTicks, sizeof( clockTicks ) ); MD5_Final( &ctx, (unsigned char *)digest ); // Quantize the 128 bit hash down to the number of bits needed for a localUserHandle_t const int STRIDE_BYTES = sizeof( localUserHandle_t::userHandleType_t ); const int NUM_LOOPS = 16 / STRIDE_BYTES; localUserHandle_t::userHandleType_t handle = 0; for ( int i = 0; i < NUM_LOOPS; i++ ) { localUserHandle_t::userHandleType_t tempHandle = 0; for ( int j = 0; j < STRIDE_BYTES; j++ ) { tempHandle |= ( ( localUserHandle_t::userHandleType_t )digest[ ( i * STRIDE_BYTES ) + j ] ) << ( j * 8 ); } handle ^= tempHandle; } return localUserHandle_t( handle ); }