1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-11-28 08:48:48 +02:00

Merge pull request #675 from ShubusCorporation/do/fix/mod_system_and_interface_bugs

Fixed: Mods dependency issues leading to hanging & 'Restart Scenario' button functionality
This commit is contained in:
Alexander Shishkin 2021-02-08 07:32:09 +03:00 committed by GitHub
commit db1f9a15b0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 32 additions and 32 deletions

View File

@ -451,6 +451,13 @@ void CServerHandler::sendStartGame(bool allowOnlyAI) const
{
verifyStateBeforeStart(allowOnlyAI ? true : settings["session"]["onlyai"].Bool());
LobbyStartGame lsg;
if(client)
{
lsg.initializedStartInfo = std::make_shared<StartInfo>(* const_cast<StartInfo *>(client->getStartInfo(true)));
lsg.initializedStartInfo->mode = StartInfo::NEW_GAME;
lsg.initializedStartInfo->seedToBeUsed = lsg.initializedStartInfo->seedPostInit = 0;
* si = * lsg.initializedStartInfo;
}
sendLobbyPack(lsg);
}

View File

@ -716,50 +716,41 @@ bool CModHandler::checkDependencies(const std::vector <TModID> & input) const
return true;
}
std::vector <TModID> CModHandler::resolveDependencies(std::vector <TModID> input) const
std::vector <TModID> CModHandler::resolveDependencies(std::vector <TModID> modsToResolve) const
{
// Topological sort algorithm
// May not be the fastest one but VCMI does not needs any speed here
// Unless user have dozens of mods with complex dependencies this code should be fine
std::vector<TModID> brokenMods;
// first - sort input to have input strictly based on name (and not on hashmap or anything else)
boost::range::sort(input);
std::vector <TModID> output;
output.reserve(input.size());
std::set <TModID> resolvedMods;
// Check if all mod dependencies are resolved (moved to resolvedMods)
auto isResolved = [&](const CModInfo & mod) -> bool
auto looksValid = [&](const CModInfo & mod) -> bool
{
auto res = true;
for(const TModID & dependency : mod.dependencies)
{
if (!vstd::contains(resolvedMods, dependency))
return false;
if(!(res = vstd::contains(modsToResolve, dependency)))
logMod->error("Mod '%s' will not work: it depends on mod '%s', which is not installed.", mod.name, dependency);
}
return true;
return res;
};
while (!input.empty())
while(true)
{
std::set <TModID> toResolve; // list of mods resolved on this iteration
for (auto it = input.begin(); it != input.end();)
for(auto mod : modsToResolve)
{
if (isResolved(allMods.at(*it)))
{
toResolve.insert(*it);
output.push_back(*it);
it = input.erase(it);
continue;
}
it++;
if(!looksValid(this->allMods.at(mod)))
brokenMods.push_back(mod);
}
resolvedMods.insert(toResolve.begin(), toResolve.end());
if(!brokenMods.empty())
{
vstd::erase_if(modsToResolve, [&](TModID mid)
{
return brokenMods.end() != std::find(brokenMods.begin(), brokenMods.end(), mid);
});
brokenMods.clear();
continue;
}
break;
}
return output;
boost::range::sort(modsToResolve);
return modsToResolve;
}
std::vector<std::string> CModHandler::getModList(std::string path)

View File

@ -228,6 +228,8 @@ void CVCMIServer::prepareToStartGame()
if(state == EServerState::GAMEPLAY)
{
restartGameplay = true;
* si = * gh->gs->initialOpts;
si->seedToBeUsed = si->seedPostInit = 0;
state = EServerState::LOBBY;
// FIXME: dirry hack to make sure old CGameHandler::run is finished
boost::this_thread::sleep(boost::posix_time::milliseconds(1000));