1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-03-19 21:10:12 +02:00

Merge pull request #5140 from IvanSavenko/crashfixes

Fixes for crashes discovered via Google Play
This commit is contained in:
Ivan Savenko 2024-12-24 15:53:23 +02:00 committed by GitHub
commit ec25eb557b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 50 additions and 13 deletions

View File

@ -18,6 +18,7 @@
#include "../lib/filesystem/Filesystem.h" #include "../lib/filesystem/Filesystem.h"
#include "../lib/logging/CBasicLogConfigurator.h" #include "../lib/logging/CBasicLogConfigurator.h"
#include "../lib/texts/Languages.h" #include "../lib/texts/Languages.h"
#include "../lib/ExceptionsCommon.h"
#include "updatedialog_moc.h" #include "updatedialog_moc.h"
#include "main.h" #include "main.h"
@ -35,8 +36,15 @@ void MainWindow::load()
CBasicLogConfigurator logConfig(VCMIDirs::get().userLogsPath() / "VCMI_Launcher_log.txt", console); CBasicLogConfigurator logConfig(VCMIDirs::get().userLogsPath() / "VCMI_Launcher_log.txt", console);
logConfig.configureDefault(); logConfig.configureDefault();
CResourceHandler::initialize(); try
CResourceHandler::load("config/filesystem.json"); {
CResourceHandler::initialize();
CResourceHandler::load("config/filesystem.json");
}
catch (const DataLoadingException & e)
{
QMessageBox::critical(this, tr("Error starting executable"), QString::fromStdString(e.what()));
}
Helper::loadSettings(); Helper::loadSettings();
} }

View File

@ -561,7 +561,7 @@ QStringList CModListView::getModsToInstall(QString mod)
potentialToInstall = modStateModel->getTopParent(potentialToInstall); potentialToInstall = modStateModel->getTopParent(potentialToInstall);
} }
if (modStateModel->isModExists(potentialToInstall) && !modStateModel->isModInstalled(potentialToInstall)) if (!modStateModel->isModInstalled(potentialToInstall))
result.push_back(potentialToInstall); result.push_back(potentialToInstall);
if (modStateModel->isModExists(potentialToInstall)) if (modStateModel->isModExists(potentialToInstall))
@ -818,7 +818,8 @@ void CModListView::installFiles(QStringList files)
ChroniclesExtractor ce(this, [&prog](float progress) { prog = progress; }); ChroniclesExtractor ce(this, [&prog](float progress) { prog = progress; });
ce.installChronicles(exe); ce.installChronicles(exe);
reload(); reload();
enableModByName("chronicles"); if (modStateModel->isModExists("chronicles"))
enableModByName("chronicles");
return true; return true;
}); });

View File

@ -65,7 +65,7 @@ bool ModStateModel::isModExists(QString modName) const
bool ModStateModel::isModInstalled(QString modName) const bool ModStateModel::isModInstalled(QString modName) const
{ {
return getMod(modName).isInstalled(); return isModExists(modName) && getMod(modName).isInstalled();
} }
bool ModStateModel::isModSettingEnabled(QString rootModName, QString modSettingName) const bool ModStateModel::isModSettingEnabled(QString rootModName, QString modSettingName) const

View File

@ -149,12 +149,14 @@ void CQuest::completeQuest(IGameCallback * cb, const CGHeroInstance *h) const
if(h->hasArt(elem)) if(h->hasArt(elem))
{ {
cb->removeArtifact(ArtifactLocation(h->id, h->getArtPos(elem, false))); cb->removeArtifact(ArtifactLocation(h->id, h->getArtPos(elem, false)));
continue;
} }
else
// perhaps artifact is part of a combined artifact?
const auto * assembly = h->getCombinedArtWithPart(elem);
if (assembly)
{ {
const auto * assembly = h->getCombinedArtWithPart(elem); auto parts = assembly->getPartsInfo(); // FIXME: causes crashes on Google Play
assert(assembly);
auto parts = assembly->getPartsInfo();
// Remove the assembly // Remove the assembly
cb->removeArtifact(ArtifactLocation(h->id, h->getArtPos(assembly))); cb->removeArtifact(ArtifactLocation(h->id, h->getArtPos(assembly)));
@ -165,7 +167,11 @@ void CQuest::completeQuest(IGameCallback * cb, const CGHeroInstance *h) const
if(ci.art->getTypeId() != elem) if(ci.art->getTypeId() != elem)
cb->giveHeroNewArtifact(h, ci.art->getTypeId(), ArtifactPosition::BACKPACK_START); cb->giveHeroNewArtifact(h, ci.art->getTypeId(), ArtifactPosition::BACKPACK_START);
} }
continue;
} }
logGlobal->error("Failed to find artifact %s in inventory of hero %s", elem.toEntity(VLC)->getJsonKey(), h->getHeroTypeID());
} }
cb->takeCreatures(h->id, mission.creatures); cb->takeCreatures(h->id, mission.creatures);

View File

@ -175,6 +175,8 @@ ModsPresetState::ModsPresetState()
auto allPresets = getAllPresets(); auto allPresets = getAllPresets();
if (!vstd::contains(allPresets, modConfig["activePreset"].String())) if (!vstd::contains(allPresets, modConfig["activePreset"].String()))
modConfig["activePreset"] = JsonNode(allPresets.front()); modConfig["activePreset"] = JsonNode(allPresets.front());
logGlobal->debug("Loading following mod settings: %s", modConfig.toCompactString());
} }
void ModsPresetState::createInitialPreset() void ModsPresetState::createInitialPreset()
@ -454,7 +456,14 @@ ModsStorage::ModsStorage(const std::vector<TModID> & modsToLoad, const JsonNode
const ModDescription & ModsStorage::getMod(const TModID & fullID) const const ModDescription & ModsStorage::getMod(const TModID & fullID) const
{ {
return mods.at(fullID); try {
return mods.at(fullID);
}
catch (const std::out_of_range & )
{
// rethrow with better error message
throw std::out_of_range("Failed to find mod " + fullID);
}
} }
TModList ModsStorage::getAllMods() const TModList ModsStorage::getAllMods() const
@ -651,7 +660,7 @@ void ModManager::tryEnableMods(const TModList & modList)
for (const auto & modName : modList) for (const auto & modName : modList)
if (!vstd::contains(testResolver.getActiveMods(), modName)) if (!vstd::contains(testResolver.getActiveMods(), modName))
throw std::runtime_error("Failed to enable mod! Mod " + modName + " remains disabled!"); logGlobal->error("Failed to enable mod '%s'! This may be caused by a recursive dependency!", modName);
updatePreset(testResolver); updatePreset(testResolver);
} }

View File

@ -445,7 +445,14 @@ void ApplyOnServerNetPackVisitor::visitLobbyDelete(LobbyDelete & pack)
if(pack.type == LobbyDelete::EType::SAVEGAME || pack.type == LobbyDelete::EType::RANDOMMAP) if(pack.type == LobbyDelete::EType::SAVEGAME || pack.type == LobbyDelete::EType::RANDOMMAP)
{ {
auto res = ResourcePath(pack.name, pack.type == LobbyDelete::EType::SAVEGAME ? EResType::SAVEGAME : EResType::MAP); auto res = ResourcePath(pack.name, pack.type == LobbyDelete::EType::SAVEGAME ? EResType::SAVEGAME : EResType::MAP);
auto file = boost::filesystem::canonical(*CResourceHandler::get()->getResourceName(res)); auto name = CResourceHandler::get()->getResourceName(res);
if (!name)
{
logGlobal->error("Failed to find resource with name '%s'", res.getOriginalName());
return;
}
auto file = boost::filesystem::canonical(*name);
boost::filesystem::remove(file); boost::filesystem::remove(file);
if(boost::filesystem::is_empty(file.parent_path())) if(boost::filesystem::is_empty(file.parent_path()))
boost::filesystem::remove(file.parent_path()); boost::filesystem::remove(file.parent_path());
@ -453,7 +460,13 @@ void ApplyOnServerNetPackVisitor::visitLobbyDelete(LobbyDelete & pack)
else if(pack.type == LobbyDelete::EType::SAVEGAME_FOLDER) else if(pack.type == LobbyDelete::EType::SAVEGAME_FOLDER)
{ {
auto res = ResourcePath("Saves/" + pack.name, EResType::DIRECTORY); auto res = ResourcePath("Saves/" + pack.name, EResType::DIRECTORY);
auto folder = boost::filesystem::canonical(*CResourceHandler::get()->getResourceName(res)); auto name = CResourceHandler::get()->getResourceName(res);
if (!name)
{
logGlobal->error("Failed to find folder with name '%s'", res.getOriginalName());
return;
}
auto folder = boost::filesystem::canonical(*name);
boost::filesystem::remove_all(folder); boost::filesystem::remove_all(folder);
} }