CAccount* CAccountManager::Get ( const char* szName ) { if ( szName && szName [ 0 ] ) { std::vector < CAccount* > results; m_List.FindAccountMatches ( &results, szName, true ); for ( uint i = 0 ; i < results.size () ; i++ ) { CAccount* pAccount = results[i]; if ( pAccount->IsRegistered () ) { return pAccount; } } } return NULL; }
// Return the name of an account which already exists, and is using the same name with one or more letters in a different case SString CAccountManager::GetActiveCaseVariation ( const SString& strName ) { // Check for exact match already existing if ( Get( strName ) ) return ""; std::vector < CAccount* > results; // Case insensitive search to find all variations m_List.FindAccountMatches ( &results, strName, false ); for ( uint i = 0 ; i < results.size () ; i++ ) { CAccount* pAccount = results[i]; if ( pAccount->IsRegistered () && pAccount->GetName () != strName ) { return pAccount->GetName (); } } return ""; }
bool CAccountManager::LogIn ( CClient* pClient, CClient* pEchoClient, const char* szAccountName, const char* szPassword ) { // Is he already logged in? if ( pClient->IsRegistered () ) { if ( pEchoClient ) pEchoClient->SendEcho ( "login: You are already logged in" ); return false; } if ( pClient->GetClientType () != CClient::CLIENT_PLAYER ) { if ( pEchoClient ) pEchoClient->SendEcho ( "login: Only players can log in" ); return false; } // Get the players details CPlayer* pPlayer = static_cast < CPlayer* > ( pClient ); SString strPlayerName = pPlayer->GetNick (); SString strPlayerIP = pPlayer->GetSourceIP (); SString strPlayerSerial = pPlayer->GetSerial (); if ( m_AccountProtect.IsFlooding ( strPlayerIP.c_str () ) ) { if ( pEchoClient ) pEchoClient->SendEcho ( SString( "login: Account locked", szAccountName ).c_str() ); CLogger::AuthPrintf ( "LOGIN: Ignoring %s trying to log in as '%s' (IP: %s Serial: %s)\n", strPlayerName.c_str (), szAccountName, strPlayerIP.c_str (), strPlayerSerial.c_str () ); return false; } // Grab the account on his nick if any CAccount* pAccount = g_pGame->GetAccountManager ()->Get ( szAccountName ); if ( !pAccount ) { if ( pEchoClient ) pEchoClient->SendEcho( SString( "login: No known account for '%s'", szAccountName ).c_str() ); CLogger::AuthPrintf ( "LOGIN: %s tried to log in as '%s' (Unknown account) (IP: %s Serial: %s)\n", strPlayerName.c_str (), szAccountName, strPlayerIP.c_str (), strPlayerSerial.c_str () ); return false; } if ( pAccount->GetClient () ) { if ( pEchoClient ) pEchoClient->SendEcho ( SString( "login: Account for '%s' is already in use", szAccountName ).c_str() ); return false; } if ( !IsValidPassword( szPassword ) || !pAccount->IsPassword ( szPassword ) ) { if ( pEchoClient ) pEchoClient->SendEcho ( SString( "login: Invalid password for account '%s'", szAccountName ).c_str() ); CLogger::AuthPrintf ( "LOGIN: %s tried to log in as '%s' with an invalid password (IP: %s Serial: %s)\n", strPlayerName.c_str (), szAccountName, strPlayerIP.c_str (), strPlayerSerial.c_str () ); m_AccountProtect.AddConnect ( strPlayerIP.c_str () ); return false; } // Check serial authorization if ( IsAuthorizedSerialRequired( pAccount ) ) { pAccount->AddSerialForAuthorization( strPlayerSerial, strPlayerIP ); if ( !pAccount->IsSerialAuthorized( strPlayerSerial ) ) { if ( pEchoClient ) pEchoClient->SendEcho( SString( "login: Serial pending authorization for account '%s' - See https:""//mtasa.com/authserial", szAccountName ) ); CLogger::AuthPrintf( "LOGIN: %s tried to log in as '%s' with an unauthorized serial (IP: %s Serial: %s)\n", *strPlayerName, szAccountName, *strPlayerIP, *strPlayerSerial ); CLogger::AuthPrintf( "LOGIN: See https:""//mtasa.com/authserial\n" ); return false; } } // Log him in CAccount* pCurrentAccount = pClient->GetAccount (); pClient->SetAccount ( pAccount ); pAccount->SetClient ( pClient ); // Call the onPlayerLogin script event CLuaArguments Arguments; Arguments.PushAccount ( pCurrentAccount ); Arguments.PushAccount ( pAccount ); Arguments.PushBoolean ( false ); // was bAutoLogin if ( !pPlayer->CallEvent ( "onPlayerLogin", Arguments ) ) { // DENIED! pClient->SetAccount ( pCurrentAccount ); pAccount->SetClient ( NULL ); return false; } // Success is here pAccount->OnLoginSuccess ( strPlayerSerial, strPlayerIP ); SString strGroupList = SString::Join ( ", ", g_pGame->GetACLManager ()->GetObjectGroupNames ( pAccount->GetName (), CAccessControlListGroupObject::OBJECT_TYPE_USER ) ); CLogger::AuthPrintf ( "LOGIN: (%s) %s successfully logged in as '%s' (IP: %s Serial: %s)\n", strGroupList.c_str (), pClient->GetNick (), pAccount->GetName ().c_str (), strPlayerIP.c_str (), strPlayerSerial.c_str () ); // Tell the player if ( pEchoClient ) { pEchoClient->SendEcho ( "login: You successfully logged in" ); } // Update who was info if ( pClient->GetClientType () == CClient::CLIENT_PLAYER ) g_pGame->GetConsole ()->GetWhoWas ()->OnPlayerLogin ( static_cast < CPlayer* > ( pClient ) ); // Delete the old account if it was a guest account if ( !pCurrentAccount->IsRegistered () ) delete pCurrentAccount; return true; }
bool CAccountManager::Load( void ) { //Create a registry result CRegistryResult result; //Select all our required information from the accounts database m_pDatabaseManager->QueryWithResultf ( m_hDbConnection, &result, "SELECT id,name,password,ip,serial,httppass from accounts" ); //Initialize all our variables m_iAccounts = 0; bool bNeedsVacuum = false; CElapsedTime activityTimer; bool bOutputFeedback = false; for ( CRegistryResultIterator iter = result->begin() ; iter != result->end() ; ++iter ) { const CRegistryResultRow& row = *iter; //Fill User ID, Name & Password (Required data) int iUserID = static_cast < int > ( row[0].nVal ); SString strName = (const char *)row[1].pVal; SString strPassword = (const char *)row[2].pVal; SString strIP = (const char *)row[3].pVal; SString strSerial = (const char *)row[4].pVal; SString strHttpPassAppend = (const char *)row[5].pVal; // Check for overlong names and incorrect escapement bool bRemoveAccount = false; bool bChanged = false; if ( strName.length () > 64 ) { // Try to repair name if ( strName.length () <= 256 ) { strName = strName.Replace ( "\"\"", "\"", true ).substr ( 0, 64 ); bChanged = true; } // If name gone doolally or account with this name already exists, remove account if ( strName.length () > 256 || Get ( strName ) ) { bNeedsVacuum = true; bRemoveAccount = true; CLogger::LogPrintf ( "Removed duplicate or damaged account for %s\n", strName.substr ( 0, 64 ).c_str() ); } } // Check for disallowed account names if ( strName == "*****" || strName == CONSOLE_ACCOUNT_NAME ) bRemoveAccount = true; // Do account remove if required if ( bRemoveAccount ) { m_pDatabaseManager->Execf ( m_hDbConnection, "DELETE FROM accounts WHERE id=?", SQLITE_INTEGER, iUserID ); m_pDatabaseManager->Execf ( m_hDbConnection, "DELETE FROM userdata WHERE userid=?", SQLITE_INTEGER, iUserID ); m_pDatabaseManager->Execf ( m_hDbConnection, "DELETE FROM serialusage WHERE userid=?", SQLITE_INTEGER, iUserID ); continue; } //Create a new account with the specified information CAccount* pAccount = g_pGame->GetAccountManager ()->AddPlayerAccount ( strName, strPassword, iUserID, strIP, strSerial, strHttpPassAppend ); if ( bChanged ) pAccount->SetChanged ( bChanged ); m_iAccounts = std::max ( m_iAccounts, iUserID ); // Feedback for the user if ( activityTimer.Get() > 5000 ) { activityTimer.Reset(); bOutputFeedback = true; CLogger::LogPrintf ( "Reading accounts %d/%d\n", m_List.size(), result->nRows ); } } if ( bOutputFeedback ) CLogger::LogPrintf ( "Reading accounts done.\n"); if ( bNeedsVacuum ) m_pDatabaseManager->Execf ( m_hDbConnection, "VACUUM" ); // Save any upgraded accounts { CElapsedTime activityTimer; bool bOutputFeedback = false; uint uiSaveCount = 0; for ( CMappedAccountList::const_iterator iter = m_List.begin () ; iter != m_List.end () ; iter++ ) { CAccount* pAccount = *iter; if ( pAccount->IsRegistered () && pAccount->HasChanged () && !pAccount->IsConsoleAccount () ) { uiSaveCount++; Save ( pAccount, false ); // Feedback for the user if ( activityTimer.Get() > 5000 ) { activityTimer.Reset(); bOutputFeedback = true; CLogger::LogPrintf ( "Saving upgraded accounts %d\n", uiSaveCount ); } } } if ( uiSaveCount > 100 ) { bOutputFeedback = true; CLogger::LogPrintf ( "Finishing accounts upgrade...\n" ); for ( uint i = 0 ; i < 10 ; i++ ) { Sleep( 10 ); m_pDatabaseManager->DoPulse (); } } if ( bOutputFeedback ) CLogger::LogPrintf ( "Completed accounts upgrade.\n"); } return true; }
bool CAccountManager::LogIn ( CClient* pClient, CClient* pEchoClient, CAccount* pAccount, bool bAutoLogin ) { // Log him in CAccount* pCurrentAccount = pClient->GetAccount (); pClient->SetAccount ( pAccount ); pAccount->SetClient ( pClient ); string strPlayerIP, strPlayerSerial; if ( pClient->GetClientType () == CClient::CLIENT_PLAYER ) { CPlayer* pPlayer = static_cast < CPlayer* > ( pClient ); // Get the players details strPlayerIP = pPlayer->GetSourceIP () ; strPlayerSerial = pPlayer->GetSerial (); // Set in account pAccount->SetIP ( strPlayerIP ); pAccount->SetSerial ( strPlayerSerial ); } // Call the onClientLogin script event CElement* pClientElement = NULL; switch ( pClient->GetClientType () ) { case CClient::CLIENT_PLAYER: { CPlayer* pPlayer = static_cast < CPlayer* > ( pClient ); pClientElement = static_cast < CElement* > ( pPlayer ); break; } case CClient::CLIENT_CONSOLE: { CConsoleClient* pConsoleClient = static_cast < CConsoleClient* > ( pClient ); pClientElement = static_cast < CElement* > ( pConsoleClient ); break; } } if ( pClientElement ) { CLuaArguments Arguments; Arguments.PushAccount ( pCurrentAccount ); Arguments.PushAccount ( pAccount ); Arguments.PushBoolean ( bAutoLogin ); if ( !pClientElement->CallEvent ( "onPlayerLogin", Arguments ) ) { // DENIED! pClient->SetAccount ( pCurrentAccount ); pAccount->SetClient ( NULL ); return false; } } // Get the names of the groups the client belongs to - I did it like this for a larf string strGroupList; for ( list <CAccessControlListGroup* > ::const_iterator iterg = g_pGame->GetACLManager ()->Groups_Begin () ; iterg != g_pGame->GetACLManager ()->Groups_End (); iterg++ ) for ( list <CAccessControlListGroupObject* > ::iterator itero = (*iterg)->IterBeginObjects () ; itero != (*iterg)->IterEndObjects (); itero++ ) if ( (*itero)->GetObjectType () == CAccessControlListGroupObject::OBJECT_TYPE_USER ) if ( (*itero)->GetObjectName () == pAccount->GetName () || strcmp ( (*itero)->GetObjectName (), "*" ) == 0 ) strGroupList = string( (*iterg)->GetGroupName () ) + ( strGroupList.length() ? ", " : "" ) + strGroupList; CLogger::AuthPrintf ( "LOGIN: (%s) %s successfully logged in as '%s' (IP: %s Serial: %s)\n", strGroupList.c_str (), pClient->GetNick (), pAccount->GetName ().c_str (), strPlayerIP.c_str (), strPlayerSerial.c_str () ); // Tell the player if ( pEchoClient ) { if ( bAutoLogin ) pEchoClient->SendEcho ( "auto-login: You successfully logged in" ); else pEchoClient->SendEcho ( "login: You successfully logged in" ); } // Update who was info if ( pClient->GetClientType () == CClient::CLIENT_PLAYER ) g_pGame->GetConsole ()->GetWhoWas ()->OnPlayerLogin ( static_cast < CPlayer* > ( pClient ) ); // Delete the old account if it was a guest account if ( !pCurrentAccount->IsRegistered () ) delete pCurrentAccount; return true; }