Esempio n. 1
0
 bool Db::Init(std::tstring const& filename)
 {
     int err = sqlite3_open(to_ascii_copy(filename).c_str(), &m_pDb);
     if (SQLITE_OK != err)
     {
         m_log << "Db::Init: failed to open file [" << to_ascii_copy(filename) << "]. Error " << err << ", " << sqlite3_errmsg(m_pDb) << std::endl;
         sqlite3_close(m_pDb);
         m_pDb = NULL;
         return false;
     }
     return true;
 }
Esempio n. 2
0
void DBManager::SetToonName(unsigned int charid, std::tstring const& newName)
{
    m_db->Begin();

    boost::format sql("INSERT OR REPLACE INTO tToons (charid, charname) VALUES (%1%, '%2%')");
    sql % charid % to_ascii_copy(newName);

    if (!m_db->Exec(sql.str()))
    {
        // Insert failed, so update existing record instead.
        sql = boost::format("UPDATE OR IGNORE tToons SET charname='%1%' WHERE charid=%2%");
        sql % to_ascii_copy(newName) % charid;
        m_db->Exec(sql.str());
    }

    m_db->Commit();
}
Esempio n. 3
0
std::tstring ContainerManager::GetContainerName(unsigned int charid, unsigned int containerid) const
{
    if (containerid == 1) {
        return _T("Bank");
    }
    else if (containerid == 2) {
        return _T("Inventory/Equip");
    }
    else if (containerid == 3) {
        return _T("Shop");
    }

    std::tstring result;

    __int64 key = ((__int64)charid) << 32;
    key += containerid;

    FILETIME lastWrite;
    lastWrite.dwHighDateTime = lastWrite.dwLowDateTime = 0;

    std::tstring filename;
    for (unsigned int i = 0; i < m_accounts.size(); i++)
    {
        filename = STREAM2STR( AOManager::instance().getAOPrefsFolder() << _T("\\") << m_accounts[i] << _T("\\Char") << charid << _T("\\Containers\\Container_51017x") << containerid << _T(".xml") );
        if (PathFileExists(filename.c_str()))
        {
            WIN32_FILE_ATTRIBUTE_DATA atribs; 
            if (GetFileAttributesEx(filename.c_str(), GetFileExInfoStandard, &atribs))
            {
                lastWrite = atribs.ftLastWriteTime;
                break;
            }
        }
    }

    bool wasInCache = m_containerFileCache.find(key) != m_containerFileCache.end();

    // Clear invalid cache
    if ((filename.empty() || (lastWrite.dwHighDateTime == 0 && lastWrite.dwHighDateTime == 0)) && wasInCache)
    {
        m_containerFileCache.erase(m_containerFileCache.find(key));
    }

    // Create cache from file
    if (!filename.empty())
    {
        bool update = true;

        // If already in cache, check timestamps
        if (m_containerFileCache.find(key) != m_containerFileCache.end())
        {
            FILETIME stamp = m_containerFileCache[key].second;
            if (stamp.dwHighDateTime == lastWrite.dwHighDateTime &&
                stamp.dwLowDateTime == lastWrite.dwLowDateTime)
            {
                update = false;
                result = m_containerFileCache[key].first;
            }
        }

        if (update)
        {
            TiXmlDocument document;
            if (document.LoadFile(to_ascii_copy(filename), TIXML_ENCODING_UTF8))
            {
                TiXmlHandle docHandle( &document );
                TiXmlElement* element = docHandle.FirstChild( "Archive" ).FirstChild( "String" ).Element();

                while (element)
                {
                    if (StrCmpA(element->Attribute("name"), "container_name") == 0)
                    {
                        result = from_utf8_copy(element->Attribute("value"));
                        boost::algorithm::replace_all(result, _T("&amp;"), _T("&"));    // Fixes wierd encoding in the AO xml.
                        m_containerFileCache[key] = std::pair<std::tstring, FILETIME>(result, lastWrite);
                        break;
                    }
                    element = element->NextSiblingElement();
                }
            }
        }
    }

    if (result.empty())
    {
        result = MakeContainerName(charid, containerid);
    }

    return result;
}
Esempio n. 4
0
 bool Db::Exec(std::wstring const& sql) const
 {
     return Exec(to_ascii_copy(sql));
 }
Esempio n. 5
0
/**
* Check to see if we have a local database already.
* If it is, then check if it is up to date.
* If local database is missing or obsolete then recreate it.
* Return true if application has a local items database to run with, false otherwise.
*/
bool DBManager::syncLocalItemsDB(std::tstring const& localfile, std::tstring const& aofolder)
{
    bool hasLocalDB = false;
    std::time_t lastUpdateTime;

    bfs::path local(to_ascii_copy (localfile));
    bfs::path original(to_ascii_copy (aofolder));
    original = original / "cd_image/data/db/ResourceDatabase.dat";

    if (bfs::exists(local) && bfs::is_regular(local))
    {
        hasLocalDB = true;
        lastUpdateTime = bfs::last_write_time(local);
    }

    if (!exists(original))
    {
        Logger::instance().log(_T("Could not locate the original AO database."));
        return hasLocalDB;
    }

    if (hasLocalDB && getAODBSchemeVersion(localfile) == CURRENT_AODB_VERSION)
    {
        std::time_t lastOriginalUpdateTime = bfs::last_write_time(original);
        if (lastOriginalUpdateTime <= lastUpdateTime)
        {
            return true;
        }

        // Ask user if he wants to continue using the old (but compatible) DB or update it now.
        int answer = ::MessageBox(NULL,
                                  _T("You items database is out of date. Do you wish to update it now?\r\nAnswering 'NO' will continue using the old one."),
                                  _T("Question - AO Item Assistant++"), MB_ICONQUESTION | MB_YESNOCANCEL);
        if (answer == IDCANCEL)
        {
            exit(0);
        }
        else if (answer == IDNO)
        {
            return true;
        }
    }

    // If we come this far we need to update the DB.

    bfs::path tmpfile("tmp_" + local.string());
    bfs::remove(tmpfile);

    try
    {
        std::set<ResourceType> resource_types = boost::assign::list_of(AODB_TYP_ITEM)(AODB_TYP_NANO);
        AODatabaseIndex indexer(to_ascii_copy(aofolder) + "/cd_image/data/db/ResourceDatabase.idx", resource_types);
        std::vector<unsigned int> item_offsets = indexer.GetOffsets(AODB_TYP_ITEM);
        std::vector<unsigned int> nano_offsets = indexer.GetOffsets(AODB_TYP_NANO);
        unsigned int itemCount = item_offsets.size();
        unsigned int nanoCount = nano_offsets.size();

        std::vector<std::string> original_files = boost::assign::list_of(original.string())(original.string()+".001")(original.string()+".002");
        AODatabaseParser aodb(original_files);
        AODatabaseWriter writer(tmpfile.string(), Logger::instance().stream());

        CProgressDialog dlg(itemCount + nanoCount, itemCount);
        dlg.SetWindowText(_T("Progress Dialog - Item Assistant"));
        dlg.setText(0, _T("Extracting data from the AO DB..."));
        dlg.setText(1, STREAM2STR("Finished " << 0 << " out of " << itemCount << " items."));
        dlg.setText(2, _T("Overall progress: 0%"));

        // Extract items
        boost::shared_ptr<ao_item> item;
        unsigned int count = 0;
        writer.BeginWrite();
        for (std::vector<unsigned int>::iterator item_it = item_offsets.begin(); item_it != item_offsets.end(); ++item_it)
        {
            item = aodb.GetItem(*item_it);
            count++;
            if (!item)
            {
                LOG(_T("Parsing item ") << count << _T(" at offset ") << *item_it << _T(" failed!"));
                continue;
            }
            writer.WriteItem(item);
            if (count % 1000 == 0) {
                if (dlg.userCanceled()) {
                    return false;
                }
                dlg.setTaskProgress(count, itemCount);
                dlg.setText(1, STREAM2STR("Finished " << count << " out of " << itemCount << " items."));
                dlg.setOverallProgress(count, itemCount + nanoCount);
                dlg.setText(2, STREAM2STR("Overall progress: " << (count * 100) / max(1, itemCount + nanoCount) << "%"));
            }
            if (count % 10000 == 0) {
                writer.CommitItems();
                writer.BeginWrite();
            }
        }
        item.reset();
        dlg.setTaskProgress(count, itemCount);
        dlg.setText(1, STREAM2STR("Finished " << count << " out of " << itemCount << " items."));
        dlg.setOverallProgress(count, itemCount + nanoCount);
        dlg.setText(2, STREAM2STR("Overall progress: " << (count * 100) / max(1, itemCount + nanoCount) << "%"));
        writer.CommitItems();

        if (dlg.userCanceled())
        {
            return false;
        }

        // Extract nano programs
        boost::shared_ptr<ao_item> nano;
        count = 0;
        writer.BeginWrite();
        for (std::vector<unsigned int>::iterator nano_it = nano_offsets.begin(); nano_it != nano_offsets.end(); ++nano_it)
        {
            nano = aodb.GetItem(*nano_it);
            count++;
            if (!nano)
            {
                LOG(_T("Parsing nano ") << count << _T(" at offset ") << *nano_it << _T(" failed!"));
                continue;
            }
            writer.WriteItem(nano);
            if (count % 1000 == 0)
            {
                if (dlg.userCanceled())
                {
                    return false;
                }
                dlg.setTaskProgress(count, nanoCount);
                dlg.setText(1, STREAM2STR("Finished " << count << " out of " << nanoCount << " nanos."));
                dlg.setOverallProgress(itemCount + count, itemCount + nanoCount);
                dlg.setText(2, STREAM2STR("Overall progress: " << ((itemCount + count) * 100) / max(1, itemCount +
                                          nanoCount) << "%"));
            }
            if (count % 10000 == 0)
            {
                writer.CommitItems();
                writer.BeginWrite();
            }
        }
        nano.reset();
        dlg.setTaskProgress(count, nanoCount);
        dlg.setText(1, STREAM2STR("Finished " << count << " out of " << nanoCount << " nanos."));
        dlg.setOverallProgress(itemCount + count, itemCount + nanoCount);
        dlg.setText(2, STREAM2STR("Overall progress: " << ((itemCount + count) * 100) / max(1, itemCount + nanoCount) << "%"));
        writer.CommitItems();

        if (dlg.userCanceled())
        {
            return false;
        }

        writer.PostProcessData();
    }
    catch (std::bad_alloc& e)
    {
        assert(false);
        LOG(_T("Error creating item database. ") << e.what());
        MessageBox(NULL,
                   _T("Unable to parse the AO database.\n\rMore details might be found in the log-file (if enabled)."),
                   _T("Error - AO Item Assistant++"), MB_OK | MB_ICONERROR);
        return false;
    }
    catch (AODatabaseParser::Exception& e)
    {
        assert(false);
        LOG(_T("Error creating item database. ") << e.what());
        MessageBox(NULL,
                   _T("Unable to parse the AO database.\n\rMore details might be found in the log-file (if enabled)."),
                   _T("Error - AO Item Assistant++"), MB_OK | MB_ICONERROR);
        return false;
    }
    catch (std::exception& e)
    {
        assert(false);
        LOG(_T("Error creating item database. ") << e.what());
        MessageBox(NULL,
                   _T("Unable to parse the AO database.\n\rMore details might be found in the log-file (if enabled)."),
                   _T("Error - AO Item Assistant++"), MB_OK | MB_ICONERROR);
        return false;
    }

    remove(local);
    rename(tmpfile, local);

    return true;
}