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; }
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(); }
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("&"), _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; }
bool Db::Exec(std::wstring const& sql) const { return Exec(to_ascii_copy(sql)); }
/** * 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; }