示例#1
0
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;
}