diff --git a/src/directoryrefresher.cpp b/src/directoryrefresher.cpp index e195d3a60..e2e05b2cc 100644 --- a/src/directoryrefresher.cpp +++ b/src/directoryrefresher.cpp @@ -208,7 +208,7 @@ void DirectoryRefresher::addModBSAToStructure(DirectoryEntry* root, { QStringList loadOrder; - auto* gamePlugins = m_Core.gameFeatures().gameFeature(); + auto gamePlugins = m_Core.gameFeatures().gameFeature(); if (gamePlugins) { loadOrder = gamePlugins->getLoadOrder(); } @@ -357,7 +357,7 @@ struct ModThread if (Settings::instance().archiveParsing()) { QStringList loadOrder; - GamePlugins* gamePlugins = gameFeatures->gameFeature(); + auto gamePlugins = gameFeatures->gameFeature(); if (gamePlugins) { loadOrder = gamePlugins->getLoadOrder(); } diff --git a/src/game_features.cpp b/src/game_features.cpp index 49dd2988c..bc083bc80 100644 --- a/src/game_features.cpp +++ b/src/game_features.cpp @@ -162,6 +162,8 @@ GameFeatures::GameFeatures(OrganizerCore* core, PluginContainer* plugins) }); } +GameFeatures::~GameFeatures() {} + GameFeatures::CombinedModDataChecker& GameFeatures::modDataChecker() const { return dynamic_cast(*m_modDataChecker); @@ -176,6 +178,12 @@ void GameFeatures::updateCurrentFeatures(std::type_index const& index) auto& features = m_allFeatures[index]; m_currentFeatures[index].clear(); + + // this can occur when starting MO2, just wait for the next update + if (!m_pluginContainer.managedGame()) { + return; + } + for (const auto& dataFeature : features) { // registering plugin is disabled @@ -202,7 +210,7 @@ void GameFeatures::updateCurrentFeatures(std::type_index const& index) return std::dynamic_pointer_cast(checker); }); modDataChecker().setCheckers(std::move(checkers)); - emit modDataCheckerUpdated(gameFeature()); + emit modDataCheckerUpdated(gameFeature().get()); } // update mod data content @@ -215,7 +223,7 @@ void GameFeatures::updateCurrentFeatures(std::type_index const& index) return std::dynamic_pointer_cast(checker); }); modDataContent().setContents(std::move(contents)); - emit modDataContentUpdated(gameFeature()); + emit modDataContentUpdated(gameFeature().get()); } } @@ -313,14 +321,14 @@ int GameFeatures::unregisterGameFeatures(MOBase::IPlugin* plugin, return removed; } -GameFeature* GameFeatures::gameFeature(std::type_info const& info) const +std::shared_ptr GameFeatures::gameFeature(std::type_info const& info) const { if (info == ModDataCheckerIndex) { - return modDataChecker().isValid() ? m_modDataChecker.get() : nullptr; + return modDataChecker().isValid() ? m_modDataChecker : nullptr; } if (info == ModDataContentIndex) { - return modDataContent().isValid() ? m_modDataContent.get() : nullptr; + return modDataContent().isValid() ? m_modDataContent : nullptr; } auto it = m_currentFeatures.find(info); @@ -328,5 +336,5 @@ GameFeature* GameFeatures::gameFeature(std::type_info const& info) const return nullptr; } - return it->second.front().get(); + return it->second.front(); } diff --git a/src/game_features.h b/src/game_features.h index 8e9a5cb35..55f35e377 100644 --- a/src/game_features.h +++ b/src/game_features.h @@ -35,6 +35,8 @@ class GameFeatures : public QObject */ GameFeatures(OrganizerCore* core, PluginContainer* plugins); + ~GameFeatures(); + // register game features // bool registerGameFeature(MOBase::IPlugin* plugin, QStringList const& games, @@ -48,9 +50,9 @@ class GameFeatures : public QObject // retrieve a game feature // template - T* gameFeature() const + std::shared_ptr gameFeature() const { - return dynamic_cast(gameFeature(typeid(T))); + return std::dynamic_pointer_cast(gameFeature(typeid(T))); } signals: @@ -88,7 +90,7 @@ class GameFeatures : public QObject // retrieve a game feature from info // - MOBase::GameFeature* gameFeature(std::type_info const& index) const; + std::shared_ptr gameFeature(std::type_info const& index) const; // update current features by filtering // @@ -108,8 +110,8 @@ class GameFeatures : public QObject std::unordered_map>> m_currentFeatures; - std::unique_ptr m_modDataChecker; - std::unique_ptr m_modDataContent; + std::shared_ptr m_modDataChecker; + std::shared_ptr m_modDataContent; }; #endif diff --git a/src/gamefeaturesproxy.cpp b/src/gamefeaturesproxy.cpp index 21e38617c..3adac3539 100644 --- a/src/gamefeaturesproxy.cpp +++ b/src/gamefeaturesproxy.cpp @@ -36,7 +36,7 @@ bool GameFeaturesProxy::unregisterFeature(std::shared_ptr f return m_Features.unregisterGameFeature(feature); } -MOBase::GameFeature* +std::shared_ptr GameFeaturesProxy::gameFeatureImpl(std::type_info const& info) const { return m_Features.gameFeature(info); diff --git a/src/gamefeaturesproxy.h b/src/gamefeaturesproxy.h index dd9cee519..9ffd6b046 100644 --- a/src/gamefeaturesproxy.h +++ b/src/gamefeaturesproxy.h @@ -3,7 +3,6 @@ #include "igamefeatures.h" - class GameFeatures; class OrganizerProxy; @@ -23,7 +22,8 @@ class GameFeaturesProxy : public MOBase::IGameFeatures bool unregisterFeature(std::shared_ptr feature) override; protected: - MOBase::GameFeature* gameFeatureImpl(std::type_info const& info) const override; + std::shared_ptr + gameFeatureImpl(std::type_info const& info) const override; int unregisterFeaturesImpl(std::type_info const& info) override; private: diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 4bbf906bb..b14a14a1b 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -1796,16 +1796,14 @@ void MainWindow::on_profileBox_currentIndexChanged(int index) activateSelectedProfile(); - LocalSavegames* saveGames = - m_OrganizerCore.gameFeatures().gameFeature(); + auto saveGames = m_OrganizerCore.gameFeatures().gameFeature(); if (saveGames != nullptr) { if (saveGames->prepareProfile(m_OrganizerCore.currentProfile())) { m_SavesTab->refreshSaveList(); } } - BSAInvalidation* invalidation = - m_OrganizerCore.gameFeatures().gameFeature(); + auto invalidation = m_OrganizerCore.gameFeatures().gameFeature(); if (invalidation != nullptr) { if (invalidation->prepareProfile(m_OrganizerCore.currentProfile())) { QTimer::singleShot(5, [this] { @@ -1923,8 +1921,7 @@ void MainWindow::updateBSAList(const QStringList& defaultArchives, ui->bsaList->header()->setSectionResizeMode(QHeaderView::ResizeToContents); std::vector> items; - BSAInvalidation* invalidation = - m_OrganizerCore.gameFeatures().gameFeature(); + auto invalidation = m_OrganizerCore.gameFeatures().gameFeature(); std::vector files = m_OrganizerCore.directoryStructure()->getFiles(); QStringList plugins = @@ -2033,7 +2030,7 @@ void MainWindow::updateBSAList(const QStringList& defaultArchives, void MainWindow::checkBSAList() { - DataArchives* archives = m_OrganizerCore.gameFeatures().gameFeature(); + auto archives = m_OrganizerCore.gameFeatures().gameFeature(); if (archives != nullptr) { ui->bsaList->blockSignals(true); @@ -2385,16 +2382,14 @@ void MainWindow::on_actionAdd_Profile_triggered() } } - LocalSavegames* saveGames = - m_OrganizerCore.gameFeatures().gameFeature(); + auto saveGames = m_OrganizerCore.gameFeatures().gameFeature(); if (saveGames != nullptr) { if (saveGames->prepareProfile(m_OrganizerCore.currentProfile())) { m_SavesTab->refreshSaveList(); } } - BSAInvalidation* invalidation = - m_OrganizerCore.gameFeatures().gameFeature(); + auto invalidation = m_OrganizerCore.gameFeatures().gameFeature(); if (invalidation != nullptr) { if (invalidation->prepareProfile(m_OrganizerCore.currentProfile())) { QTimer::singleShot(5, [this] { diff --git a/src/modinfo.cpp b/src/modinfo.cpp index d7943d360..abfd9de6c 100644 --- a/src/modinfo.cpp +++ b/src/modinfo.cpp @@ -249,9 +249,9 @@ void ModInfo::updateFromDisc(const QString& modsDirectory, OrganizerCore& core, } } - auto* game = core.managedGame(); - auto& features = core.pluginContainer().gameFeatures(); - auto* unmanaged = features.gameFeature(); + auto* game = core.managedGame(); + auto& features = core.pluginContainer().gameFeatures(); + auto unmanaged = features.gameFeature(); if (unmanaged != nullptr) { for (const QString& modName : unmanaged->mods(!displayForeign)) { ModInfo::EModType modType = diff --git a/src/modinforegular.cpp b/src/modinforegular.cpp index 43949fb4a..d3ff65472 100644 --- a/src/modinforegular.cpp +++ b/src/modinforegular.cpp @@ -703,7 +703,7 @@ std::vector ModInfoRegular::getFlags() const std::set ModInfoRegular::doGetContents() const { - ModDataContent* contentFeature = + auto contentFeature = m_Core.pluginContainer().gameFeatures().gameFeature(); if (contentFeature) { diff --git a/src/organizer_en.ts b/src/organizer_en.ts index 812b03f9d..3ca67ae27 100644 --- a/src/organizer_en.ts +++ b/src/organizer_en.ts @@ -3261,7 +3261,7 @@ This is likely due to a corrupted or incompatible download or unrecognized archi - + Sort the plugins using LOOT. @@ -3653,7 +3653,7 @@ This is likely due to a corrupted or incompatible download or unrecognized archi - + Endorse Mod Organizer @@ -3950,281 +3950,281 @@ As a final option, you can disable Nexus category mapping altogether, which can - + <Edit...> - + (no executables) - + This bsa is enabled in the ini file so it may be required! - + Activating Network Proxy - + Notice: Your current MO version (%1) is lower than the previously used one (%2). The GUI may not downgrade gracefully, so you may experience oddities. However, there should be no serious issues. - + failed to change origin name: %1 - + failed to move "%1" from mod "%2" to "%3": %4 - + Open Game folder - + Open MyGames folder - + Open INIs folder - + Open Instance folder - + Open Mods folder - + Open Profile folder - + Open Downloads folder - + Open MO2 Install folder - + Open MO2 Plugins folder - + Open MO2 Stylesheets folder - + Open MO2 Logs folder - + Restart Mod Organizer - + Mod Organizer must restart to finish configuration changes - + Restart - + Continue - + Some things might be weird. - + Can't change download directory while downloads are in progress! - + Update available - + Do you want to endorse Mod Organizer on %1 now? - + Abstain from Endorsing Mod Organizer - + Are you sure you want to abstain from endorsing Mod Organizer 2? You will have to visit the mod page on the %1 Nexus site to change your mind. - + Thank you for endorsing MO2! :) - + Please reconsider endorsing MO2 on Nexus! - + There is no supported sort mechanism for this game. You will probably have to use a third-party tool. - + None of your %1 mods appear to have had recent file updates. - + All of your mods have been checked recently. We restrict update checks to help preserve your available API requests. - + Thank you! - + Thank you for your endorsement! - + Mod ID %1 no longer seems to be available on Nexus. - + Error %1: Request to Nexus failed: %2 - - + + failed to read %1: %2 - + Error - + failed to extract %1 (errorcode %2) - + Extract BSA - + This archive contains invalid hashes. Some files may be broken. - + Extract... - + Remove '%1' from the toolbar - + Backup of load order created - + Choose backup to restore - + No Backups - + There are no backups to restore - - + + Restore failed - - + + Failed to restore the backup. Errorcode: %1 - + Backup of mod list created - + A file with the same name has already been downloaded. What would you like to do? - + Overwrite - + Rename new file - + Ignore file @@ -7610,13 +7610,13 @@ Destination: - - + + <Manage...> - + failed to parse profile %1: %2 diff --git a/src/organizercore.cpp b/src/organizercore.cpp index 163738d71..a3f7f21c9 100644 --- a/src/organizercore.cpp +++ b/src/organizercore.cpp @@ -1249,7 +1249,7 @@ void OrganizerCore::refreshBSAList() { TimeThis tt("OrganizerCore::refreshBSAList()"); - auto* archives = gameFeatures().gameFeature(); + auto archives = gameFeatures().gameFeature(); if (archives != nullptr) { m_ArchivesInit = false; @@ -2044,7 +2044,7 @@ std::vector OrganizerCore::fileMapping(const QString& profileName, } if (m_CurrentProfile->localSavesEnabled()) { - LocalSavegames* localSaves = gameFeatures().gameFeature(); + auto localSaves = gameFeatures().gameFeature(); if (localSaves != nullptr) { MappingType saveMap = localSaves->mappings(currentProfile()->absolutePath() + "/saves"); diff --git a/src/pluginlist.cpp b/src/pluginlist.cpp index 8953d0e15..748ffbada 100644 --- a/src/pluginlist.cpp +++ b/src/pluginlist.cpp @@ -177,7 +177,7 @@ void PluginList::refresh(const QString& profileName, QStringList primaryPlugins = m_GamePlugin->primaryPlugins(); QStringList enabledPlugins = m_GamePlugin->enabledPlugins(); - GamePlugins* gamePlugins = m_Organizer.gameFeatures().gameFeature(); + auto gamePlugins = m_Organizer.gameFeatures().gameFeature(); const bool lightPluginsAreSupported = gamePlugins ? gamePlugins->lightPluginsAreSupported() : false; const bool overridePluginsAreSupported = @@ -673,7 +673,7 @@ void PluginList::writeLockedOrder(const QString& fileName) const void PluginList::saveTo(const QString& lockedOrderFileName) const { - GamePlugins* gamePlugins = m_Organizer.gameFeatures().gameFeature(); + auto gamePlugins = m_Organizer.gameFeatures().gameFeature(); if (gamePlugins) { gamePlugins->writePluginLists(m_Organizer.managedGameOrganizer()->pluginList()); } @@ -1085,7 +1085,7 @@ void PluginList::generatePluginIndexes() int numESLs = 0; int numSkipped = 0; - GamePlugins* gamePlugins = m_Organizer.gameFeatures().gameFeature(); + auto gamePlugins = m_Organizer.gameFeatures().gameFeature(); const bool lightPluginsSupported = gamePlugins ? gamePlugins->lightPluginsAreSupported() : false; const bool overridePluginsSupported = @@ -1358,7 +1358,7 @@ QVariant PluginList::tooltipData(const QModelIndex& modelIndex) const } if (esp.forceDisabled) { - auto* feature = m_Organizer.gameFeatures().gameFeature(); + auto feature = m_Organizer.gameFeatures().gameFeature(); if (feature && esp.hasLightExtension && feature->lightPluginsAreSupported()) { toolTip += "

" + tr("Light plugins (ESL) are not supported by this game."); } else { diff --git a/src/profile.cpp b/src/profile.cpp index 0c05e6832..a0c5a2d4b 100644 --- a/src/profile.cpp +++ b/src/profile.cpp @@ -193,9 +193,9 @@ void Profile::findProfileSettings() } if (setting("", "AutomaticArchiveInvalidation") == QVariant()) { - auto* invalidation = m_GameFeatures.gameFeature(); - DataArchives* dataArchives = m_GameFeatures.gameFeature(); - bool found = false; + auto invalidation = m_GameFeatures.gameFeature(); + auto dataArchives = m_GameFeatures.gameFeature(); + bool found = false; if ((invalidation != nullptr) && (dataArchives != nullptr)) { for (const QString& archive : dataArchives->archives(this)) { if (invalidation->isInvalidationBSA(archive)) { @@ -813,8 +813,8 @@ void Profile::mergeTweaks(ModInfo::Ptr modInfo, const QString& tweakedIni) const bool Profile::invalidationActive(bool* supported) const { - auto* invalidation = m_GameFeatures.gameFeature(); - auto* dataArchives = m_GameFeatures.gameFeature(); + auto invalidation = m_GameFeatures.gameFeature(); + auto dataArchives = m_GameFeatures.gameFeature(); if (supported != nullptr) { *supported = ((invalidation != nullptr) && (dataArchives != nullptr)); @@ -827,7 +827,7 @@ bool Profile::invalidationActive(bool* supported) const void Profile::deactivateInvalidation() { - auto* invalidation = m_GameFeatures.gameFeature(); + auto invalidation = m_GameFeatures.gameFeature(); if (invalidation != nullptr) { invalidation->deactivate(this); @@ -838,7 +838,7 @@ void Profile::deactivateInvalidation() void Profile::activateInvalidation() { - auto* invalidation = m_GameFeatures.gameFeature(); + auto invalidation = m_GameFeatures.gameFeature(); if (invalidation != nullptr) { invalidation->activate(this); diff --git a/src/profilesdialog.cpp b/src/profilesdialog.cpp index 72c1ae721..24eddc204 100644 --- a/src/profilesdialog.cpp +++ b/src/profilesdialog.cpp @@ -72,7 +72,7 @@ ProfilesDialog::ProfilesDialog(const QString& profileName, OrganizerCore& organi } } - auto* invalidation = m_GameFeatures.gameFeature(); + auto invalidation = m_GameFeatures.gameFeature(); if (invalidation == nullptr) { ui->invalidationBox->setToolTip( tr("Archive invalidation isn't required for this game.")); diff --git a/src/savestab.cpp b/src/savestab.cpp index 540afc0c6..2cbd17de9 100644 --- a/src/savestab.cpp +++ b/src/savestab.cpp @@ -62,7 +62,7 @@ void SavesTab::displaySaveGameInfo(QTreeWidgetItem* newItem) } if (m_CurrentSaveView == nullptr) { - const SaveGameInfo* info = m_core.gameFeatures().gameFeature(); + auto info = m_core.gameFeatures().gameFeature(); if (info != nullptr) { m_CurrentSaveView = info->getSaveGameWidget(m_window); @@ -198,7 +198,7 @@ void SavesTab::refreshSaveList() void SavesTab::deleteSavegame() { - SaveGameInfo const* info = m_core.gameFeatures().gameFeature(); + auto info = m_core.gameFeatures().gameFeature(); QString savesMsgLabel; QStringList deleteFiles; @@ -245,7 +245,7 @@ void SavesTab::onContextMenu(const QPoint& pos) QMenu menu; - SaveGameInfo const* info = m_core.gameFeatures().gameFeature(); + auto info = m_core.gameFeatures().gameFeature(); if (info != nullptr) { QAction* action = menu.addAction(tr("Fix enabled mods...")); action->setEnabled(false); @@ -303,7 +303,7 @@ void SavesTab::fixMods(SaveGameInfo::MissingAssets const& missingAssets) void SavesTab::openInExplorer() { - const SaveGameInfo* info = m_core.gameFeatures().gameFeature(); + auto info = m_core.gameFeatures().gameFeature(); const auto sel = ui.list->selectionModel()->selectedRows(); if (sel.empty()) {