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; }