mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-28 23:06:24 +02:00
Redesign mod incompatibility message
This commit is contained in:
parent
60eef59bc9
commit
dce1ac1538
@ -30,9 +30,9 @@
|
||||
"vcmi.capitalColors.6" : "褐色",
|
||||
"vcmi.capitalColors.7" : "粉色",
|
||||
|
||||
"vcmi.server.errors.existingProcess" : "一个VCMI进程已经在运行,启动新进程前请结束它。",
|
||||
"vcmi.server.errors.modsIncompatibility" : "需要加载的MOD列表:",
|
||||
"vcmi.server.confirmReconnect" : "您想要重连上一个会话么?",
|
||||
"vcmi.server.errors.existingProcess" : "一个VCMI进程已经在运行,启动新进程前请结束它。",
|
||||
"vcmi.server.errors.modsToEnable" : "{需要加载的MOD列表}",
|
||||
"vcmi.server.confirmReconnect" : "您想要重连上一个会话么?",
|
||||
|
||||
"vcmi.settingsMainWindow.generalTab.hover" : "常规",
|
||||
"vcmi.settingsMainWindow.generalTab.help" : "切换到“常规”选项卡 - 设置游戏客户端呈现",
|
||||
|
@ -48,9 +48,9 @@
|
||||
"vcmi.lobby.filename" : "Název souboru",
|
||||
"vcmi.lobby.creationDate" : "Datum vytvoření",
|
||||
|
||||
"vcmi.server.errors.existingProcess" : "Již běží jiný server VCMI. Prosím, ukončete ho před startem nové hry.",
|
||||
"vcmi.server.errors.modsIncompatibility" : "Následující modifikace jsou nutné pro načtení hry:",
|
||||
"vcmi.server.confirmReconnect" : "Chcete se připojit k poslední relaci?",
|
||||
"vcmi.server.errors.existingProcess" : "Již běží jiný server VCMI. Prosím, ukončete ho před startem nové hry.",
|
||||
"vcmi.server.errors.modsToEnable" : "{Následující modifikace jsou nutné pro načtení hry}",
|
||||
"vcmi.server.confirmReconnect" : "Chcete se připojit k poslední relaci?",
|
||||
|
||||
"vcmi.settingsMainWindow.generalTab.hover" : "Obecné",
|
||||
"vcmi.settingsMainWindow.generalTab.help" : "Přepne na kartu obecných nastavení, která obsahuje nastavení související s obecným chováním klienta hry",
|
||||
|
@ -53,9 +53,10 @@
|
||||
"vcmi.lobby.filename" : "Filename",
|
||||
"vcmi.lobby.creationDate" : "Creation date",
|
||||
|
||||
"vcmi.server.errors.existingProcess" : "Another VCMI server process is running. Please terminate it before starting a new game.",
|
||||
"vcmi.server.errors.modsIncompatibility" : "The following mods are required to load the game:",
|
||||
"vcmi.server.confirmReconnect" : "Do you want to reconnect to the last session?",
|
||||
"vcmi.server.errors.existingProcess" : "Another VCMI server process is running. Please terminate it before starting a new game.",
|
||||
"vcmi.server.errors.modsToEnable" : "{Following mods are required}",
|
||||
"vcmi.server.errors.modsToDisable" : "{Following mods must be disabled}",
|
||||
"vcmi.server.confirmReconnect" : "Do you want to reconnect to the last session?",
|
||||
|
||||
"vcmi.settingsMainWindow.generalTab.hover" : "General",
|
||||
"vcmi.settingsMainWindow.generalTab.help" : "Switches to General Options tab, which contains settings related to general game client behavior.",
|
||||
|
@ -38,9 +38,9 @@
|
||||
"vcmi.mainMenu.joinTCP" : "Rejoindre TCP/IP jeu",
|
||||
"vcmi.mainMenu.playerName" : "Joueur",
|
||||
|
||||
"vcmi.server.errors.existingProcess" : "Un autre processus de serveur VCMI est en cours d'exécution. Veuillez l'arrêter' avant de démarrer un nouveau jeu.",
|
||||
"vcmi.server.errors.modsIncompatibility" : "Les mods suivants sont nécessaires pour charger le jeu :",
|
||||
"vcmi.server.confirmReconnect" : "Voulez-vous vous reconnecter à la dernière session ?",
|
||||
"vcmi.server.errors.existingProcess" : "Un autre processus de serveur VCMI est en cours d'exécution. Veuillez l'arrêter' avant de démarrer un nouveau jeu.",
|
||||
"vcmi.server.errors.modsToEnable" : "{Les mods suivants sont nécessaires pour charger le jeu}",
|
||||
"vcmi.server.confirmReconnect" : "Voulez-vous vous reconnecter à la dernière session ?",
|
||||
|
||||
"vcmi.settingsMainWindow.generalTab.hover" : "Général",
|
||||
"vcmi.settingsMainWindow.generalTab.help" : "Passe à l'onglet Options générales, qui contient des paramètres liés au comportement général du client de jeu",
|
||||
|
@ -52,9 +52,9 @@
|
||||
"vcmi.lobby.filename" : "Dateiname",
|
||||
"vcmi.lobby.creationDate" : "Erstellungsdatum",
|
||||
|
||||
"vcmi.server.errors.existingProcess" : "Es läuft ein weiterer vcmiserver-Prozess, bitte beendet diesen zuerst",
|
||||
"vcmi.server.errors.modsIncompatibility" : "Erforderliche Mods um das Spiel zu laden:",
|
||||
"vcmi.server.confirmReconnect" : "Mit der letzten Sitzung verbinden?",
|
||||
"vcmi.server.errors.existingProcess" : "Es läuft ein weiterer vcmiserver-Prozess, bitte beendet diesen zuerst",
|
||||
"vcmi.server.errors.modsToEnable" : "{Erforderliche Mods um das Spiel zu laden}",
|
||||
"vcmi.server.confirmReconnect" : "Mit der letzten Sitzung verbinden?",
|
||||
|
||||
"vcmi.settingsMainWindow.generalTab.hover" : "Allgemein",
|
||||
"vcmi.settingsMainWindow.generalTab.help" : "Wechselt zur Registerkarte Allgemeine Optionen, die Einstellungen zum allgemeinen Verhalten des Spielclients enthält.",
|
||||
|
@ -47,9 +47,9 @@
|
||||
"vcmi.lobby.filename" : "Nazwa pliku",
|
||||
"vcmi.lobby.creationDate" : "Data utworzenia",
|
||||
|
||||
"vcmi.server.errors.existingProcess" : "Inny proces 'vcmiserver' został już uruchomiony, zakończ go nim przejdziesz dalej",
|
||||
"vcmi.server.errors.modsIncompatibility" : "Następujące mody są wymagane do wczytania gry:",
|
||||
"vcmi.server.confirmReconnect" : "Połączyć ponownie z ostatnią sesją?",
|
||||
"vcmi.server.errors.existingProcess" : "Inny proces 'vcmiserver' został już uruchomiony, zakończ go nim przejdziesz dalej",
|
||||
"vcmi.server.errors.modsToEnable" : "{Następujące mody są wymagane do wczytania gry}",
|
||||
"vcmi.server.confirmReconnect" : "Połączyć ponownie z ostatnią sesją?",
|
||||
|
||||
"vcmi.settingsMainWindow.generalTab.hover" : "Ogólne",
|
||||
"vcmi.settingsMainWindow.generalTab.help" : "Przełącza do zakładki opcji ogólnych, która zawiera ustawienia związane z ogólnym działaniem gry",
|
||||
|
@ -21,9 +21,9 @@
|
||||
"vcmi.adventureMap.moveCostDetails" : "Очки движения - Стоимость: %TURNS ходов + %POINTS очков, Останется: %REMAINING очков",
|
||||
"vcmi.adventureMap.moveCostDetailsNoTurns" : "Очки движения - Стоимость: %POINTS очков, Останется: %REMAINING очков",
|
||||
|
||||
"vcmi.server.errors.existingProcess" : "Запущен другой процесс vcmiserver, сначала завершите его.",
|
||||
"vcmi.server.errors.modsIncompatibility" : "Требуемые моды для загрузки игры:",
|
||||
"vcmi.server.confirmReconnect" : "Подключиться к предыдущей сессии?",
|
||||
"vcmi.server.errors.existingProcess" : "Запущен другой процесс vcmiserver, сначала завершите его.",
|
||||
"vcmi.server.errors.modsToEnable" : "{Требуемые моды для загрузки игры}",
|
||||
"vcmi.server.confirmReconnect" : "Подключиться к предыдущей сессии?",
|
||||
|
||||
"vcmi.settingsMainWindow.generalTab.hover" : "Общее",
|
||||
"vcmi.settingsMainWindow.generalTab.help" : "Переключиться на вкладку \"Общее\", содержащее общие настройки клиента игры",
|
||||
|
@ -30,9 +30,9 @@
|
||||
"vcmi.capitalColors.6" : "Turquesa",
|
||||
"vcmi.capitalColors.7" : "Rosa",
|
||||
|
||||
"vcmi.server.errors.existingProcess" : "Otro proceso de vcmiserver está en ejecución, por favor termínalo primero",
|
||||
"vcmi.server.errors.modsIncompatibility" : "Mods necesarios para cargar el juego:",
|
||||
"vcmi.server.confirmReconnect" : "¿Conectar a la última sesión?",
|
||||
"vcmi.server.errors.existingProcess" : "Otro proceso de vcmiserver está en ejecución, por favor termínalo primero",
|
||||
"vcmi.server.errors.modsToEnable" : "{Mods necesarios para cargar el juego}",
|
||||
"vcmi.server.confirmReconnect" : "¿Conectar a la última sesión?",
|
||||
|
||||
"vcmi.settingsMainWindow.generalTab.hover" : "General",
|
||||
"vcmi.settingsMainWindow.generalTab.help" : "Cambiar a la pestaña de opciones generales, que contiene ajustes relacionados con el comportamiento general del juego",
|
||||
|
@ -48,9 +48,9 @@
|
||||
"vcmi.lobby.filename" : "Назва файлу",
|
||||
"vcmi.lobby.creationDate" : "Дата створення",
|
||||
|
||||
"vcmi.server.errors.existingProcess" : "Працює інший процес vcmiserver, будь ласка, спочатку завершіть його",
|
||||
"vcmi.server.errors.modsIncompatibility" : "Потрібні модифікації для завантаження гри:",
|
||||
"vcmi.server.confirmReconnect" : "Підключитися до минулої сесії?",
|
||||
"vcmi.server.errors.existingProcess" : "Працює інший процес vcmiserver, будь ласка, спочатку завершіть його",
|
||||
"vcmi.server.errors.modsToEnable" : "{Потрібні модифікації для завантаження гри}",
|
||||
"vcmi.server.confirmReconnect" : "Підключитися до минулої сесії?",
|
||||
|
||||
"vcmi.settingsMainWindow.generalTab.hover" : "Загальні",
|
||||
"vcmi.settingsMainWindow.generalTab.help" : "Перемикає на вкладку загальних параметрів, яка містить налаштування, пов'язані із загальною поведінкою ігрового клієнта",
|
||||
|
@ -552,10 +552,17 @@ bool CServerHandler::validateGameStart(bool allowOnlyAI) const
|
||||
catch(ModIncompatibility & e)
|
||||
{
|
||||
logGlobal->warn("Incompatibility exception during start scenario: %s", e.what());
|
||||
|
||||
auto errorMsg = CGI->generaltexth->translate("vcmi.server.errors.modsIncompatibility") + '\n';
|
||||
errorMsg += e.what();
|
||||
|
||||
std::string errorMsg;
|
||||
if(!e.whatMissing().empty())
|
||||
{
|
||||
errorMsg += VLC->generaltexth->translate("vcmi.server.errors.modsToEnable") + '\n';
|
||||
errorMsg += e.whatMissing();
|
||||
}
|
||||
if(!e.whatExcessive().empty())
|
||||
{
|
||||
errorMsg += VLC->generaltexth->translate("vcmi.server.errors.modsToDisable") + '\n';
|
||||
errorMsg += e.whatExcessive();
|
||||
}
|
||||
showServerError(errorMsg);
|
||||
return false;
|
||||
}
|
||||
|
@ -29,7 +29,6 @@
|
||||
#include "../../lib/CGeneralTextHandler.h"
|
||||
#include "../../lib/campaign/CampaignHandler.h"
|
||||
#include "../../lib/mapping/CMapInfo.h"
|
||||
#include "../../lib/modding/ModIncompatibility.h"
|
||||
#include "../../lib/rmg/CMapGenOptions.h"
|
||||
|
||||
CLobbyScreen::CLobbyScreen(ESelectionScreen screenType)
|
||||
|
@ -74,12 +74,12 @@ void LobbyInfo::verifyStateBeforeStart(bool ignoreNoHuman) const
|
||||
throw std::domain_error(VLC->generaltexth->translate("core.genrltxt.529"));
|
||||
|
||||
auto missingMods = CMapService::verifyMapHeaderMods(*mi->mapHeader);
|
||||
ModIncompatibility::ModList modList;
|
||||
ModIncompatibility::ModListWithVersion modList;
|
||||
for(const auto & m : missingMods)
|
||||
modList.push_back({m.second.name, m.second.version.toString()});
|
||||
|
||||
if(!modList.empty())
|
||||
throw ModIncompatibility(std::move(modList));
|
||||
throw ModIncompatibility(modList);
|
||||
|
||||
//there must be at least one human player before game can be started
|
||||
std::map<PlayerColor, PlayerSettings>::const_iterator i;
|
||||
|
@ -481,6 +481,10 @@ void CModHandler::trySetActiveMods(const std::vector<std::pair<TModID, CModInfo:
|
||||
return nullptr;
|
||||
};
|
||||
|
||||
std::vector<TModID> newActiveMods, missingMods, excessiveMods;
|
||||
ModIncompatibility::ModListWithVersion missingModsResult;
|
||||
ModIncompatibility::ModList excessiveModsResult;
|
||||
|
||||
for(const auto & m : activeMods)
|
||||
{
|
||||
if(searchVerificationInfo(m))
|
||||
@ -488,11 +492,11 @@ void CModHandler::trySetActiveMods(const std::vector<std::pair<TModID, CModInfo:
|
||||
|
||||
//TODO: support actual disabling of these mods
|
||||
if(getModInfo(m).checkModGameplayAffecting())
|
||||
{
|
||||
excessiveMods.push_back(m);
|
||||
allMods[m].setEnabled(false);
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<TModID> newActiveMods, missingMods;
|
||||
ModIncompatibility::ModList missingModsResult;
|
||||
|
||||
for(const auto & infoPair : modList)
|
||||
{
|
||||
@ -539,9 +543,17 @@ void CModHandler::trySetActiveMods(const std::vector<std::pair<TModID, CModInfo:
|
||||
missingModsResult.push_back({vInfo->name, vInfo->version.toString()});
|
||||
}
|
||||
}
|
||||
for(auto & m : excessiveMods)
|
||||
{
|
||||
auto & vInfo = getModInfo(m).getVerificationInfo();
|
||||
assert(vInfo.parent != m);
|
||||
if(!vInfo.parent.empty() && vstd::contains(excessiveMods, vInfo.parent))
|
||||
continue;
|
||||
excessiveModsResult.push_back(vInfo.name);
|
||||
}
|
||||
|
||||
if(!missingModsResult.empty())
|
||||
throw ModIncompatibility(std::move(missingModsResult));
|
||||
if(!missingModsResult.empty() || !excessiveModsResult.empty())
|
||||
throw ModIncompatibility(missingModsResult, excessiveModsResult);
|
||||
|
||||
//TODO: support actual enabling of these mods
|
||||
for(auto & m : newActiveMods)
|
||||
|
@ -14,29 +14,44 @@ VCMI_LIB_NAMESPACE_BEGIN
|
||||
class DLL_LINKAGE ModIncompatibility: public std::exception
|
||||
{
|
||||
public:
|
||||
using StringPair = std::pair<const std::string, const std::string>;
|
||||
using ModList = std::list<StringPair>;
|
||||
using ModListWithVersion = std::vector<std::pair<const std::string, const std::string>>;
|
||||
using ModList = std::vector<const std::string>;
|
||||
|
||||
ModIncompatibility(ModList && _missingMods):
|
||||
missingMods(std::move(_missingMods))
|
||||
ModIncompatibility(const ModListWithVersion & _missingMods)
|
||||
{
|
||||
std::ostringstream _ss;
|
||||
for(const auto & m : missingMods)
|
||||
for(const auto & m : _missingMods)
|
||||
_ss << m.first << ' ' << m.second << std::endl;
|
||||
message = _ss.str();
|
||||
messageMissingMods = _ss.str();
|
||||
}
|
||||
|
||||
|
||||
ModIncompatibility(const ModListWithVersion & _missingMods, ModList & _excessiveMods)
|
||||
: ModIncompatibility(_missingMods)
|
||||
{
|
||||
std::ostringstream _ss;
|
||||
for(const auto & m : _excessiveMods)
|
||||
_ss << m << std::endl;
|
||||
messageExcessiveMods = _ss.str();
|
||||
}
|
||||
|
||||
const char * what() const noexcept override
|
||||
{
|
||||
return message.c_str();
|
||||
static const std::string w("Mod incompatibility exception");
|
||||
return w.c_str();
|
||||
}
|
||||
|
||||
const std::string & whatMissing() const noexcept
|
||||
{
|
||||
return messageMissingMods;
|
||||
}
|
||||
|
||||
const std::string & whatExcessive() const noexcept
|
||||
{
|
||||
return messageExcessiveMods;
|
||||
}
|
||||
|
||||
private:
|
||||
//list of mods required to load the game
|
||||
// first: mod name
|
||||
// second: mod version
|
||||
const ModList missingMods;
|
||||
std::string message;
|
||||
std::string messageMissingMods, messageExcessiveMods;
|
||||
};
|
||||
|
||||
VCMI_LIB_NAMESPACE_END
|
||||
|
@ -336,19 +336,20 @@ bool MainWindow::openMap(const QString & filenameSelect)
|
||||
if(auto header = mapService.loadMapHeader(resId))
|
||||
{
|
||||
auto missingMods = CMapService::verifyMapHeaderMods(*header);
|
||||
ModIncompatibility::ModList modList;
|
||||
ModIncompatibility::ModListWithVersion modList;
|
||||
for(const auto & m : missingMods)
|
||||
modList.push_back({m.second.name, m.second.version.toString()});
|
||||
|
||||
if(!modList.empty())
|
||||
throw ModIncompatibility(std::move(modList));
|
||||
throw ModIncompatibility(modList);
|
||||
|
||||
controller.setMap(mapService.loadMap(resId));
|
||||
}
|
||||
}
|
||||
catch(const ModIncompatibility & e)
|
||||
{
|
||||
QMessageBox::warning(this, "Mods requiered", e.what());
|
||||
assert(e.whatExcessive().empty());
|
||||
QMessageBox::warning(this, "Mods are requiered", QString::fromStdString(e.whatMissing()));
|
||||
return false;
|
||||
}
|
||||
catch(const std::exception & e)
|
||||
|
@ -1765,8 +1765,17 @@ bool CGameHandler::load(const std::string & filename)
|
||||
catch(const ModIncompatibility & e)
|
||||
{
|
||||
logGlobal->error("Failed to load game: %s", e.what());
|
||||
auto errorMsg = VLC->generaltexth->translate("vcmi.server.errors.modsIncompatibility") + '\n';
|
||||
errorMsg += e.what();
|
||||
std::string errorMsg;
|
||||
if(!e.whatMissing().empty())
|
||||
{
|
||||
errorMsg += VLC->generaltexth->translate("vcmi.server.errors.modsToEnable") + '\n';
|
||||
errorMsg += e.whatMissing();
|
||||
}
|
||||
if(!e.whatExcessive().empty())
|
||||
{
|
||||
errorMsg += VLC->generaltexth->translate("vcmi.server.errors.modsToDisable") + '\n';
|
||||
errorMsg += e.whatExcessive();
|
||||
}
|
||||
lobby->announceMessage(errorMsg);
|
||||
return false;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user