Bläddra i källkod

Merge pull request #6193 from MichalZr6/mod_incompability_errors

Rework handling some errors and uncought exceptions
Ivan Savenko 2 veckor sedan
förälder
incheckning
19ff1a224c

+ 1 - 1
Mods/vcmi/Content/config/chinese.json

@@ -249,7 +249,7 @@
 	"vcmi.server.errors.existingProcess"     : "一个VCMI进程已经在运行,启动新进程前请结束它。",
 	"vcmi.server.errors.modsToEnable"    : "{需要启用的mod列表}",
 	"vcmi.server.errors.modsToDisable"   : "{需要禁用的mod列表}",
-	"vcmi.server.errors.unknownEntity" : "加载保存失败! 在保存的游戏中发现未知实体'%s'! 保存可能与当前安装的mod版本不兼容!",
+	"vcmi.server.errors.saveFile.unknownEntity" : "加载保存失败! 在保存的游戏中发现未知实体'%s'! 保存可能与当前安装的mod版本不兼容!",
 	"vcmi.server.errors.wrongIdentified"   : "你被识别为玩家%s,但预期是玩家%s。",
 	"vcmi.server.errors.notAllowed"   : "你无权执行此操作!",
 

+ 1 - 1
Mods/vcmi/Content/config/czech.json

@@ -249,7 +249,7 @@
 	"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.errors.modsToDisable"   : "{Následující modifikace musí být zakázány}",
-	"vcmi.server.errors.unknownEntity" : "Nelze načíst uloženou pozici! Neznámá entita '%s' nalezena v uložené pozici! Uložná pozice nemusí být kompatibilní s aktuálními verzemi modifikací!",
+	"vcmi.server.errors.saveFile.unknownEntity" : "Nelze načíst uloženou pozici! Neznámá entita '%s' nalezena v uložené pozici! Uložná pozice nemusí být kompatibilní s aktuálními verzemi modifikací!",
 	"vcmi.server.errors.wrongIdentified" : "Byli jste identifikováni jako hráč %s, zatímco byl očekáván hráč %s.",
 	"vcmi.server.errors.notAllowed" : "Nemáte oprávnění provést tuto akci!",
 	

+ 2 - 1
Mods/vcmi/Content/config/english.json

@@ -249,7 +249,8 @@
 	"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.errors.unknownEntity" : "Failed to load save! Unknown entity '%s' found in saved game! Save may not be compatible with currently installed version of mods!",
+	"vcmi.server.errors.saveFile.unknownEntity" : "Failed to load save! Unknown entity '%s' found in saved game! Save may not be compatible with currently installed version of mods!",
+	"vcmi.server.errors.campOrMapFile.unknownEntity" : "Failed to load file! Unknown entity '%s' found! File may not be compatible with currently installed version of mods!",
 	"vcmi.server.errors.wrongIdentified"   : "You were identified as player %s while expecting %s",
 	"vcmi.server.errors.notAllowed"   : "You are not allowed to perform this action!",
 	

+ 1 - 1
Mods/vcmi/Content/config/german.json

@@ -249,7 +249,7 @@
 	"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.errors.modsToDisable"   : "{Folgende Mods müssen deaktiviert werden}",
-	"vcmi.server.errors.unknownEntity" : "Spielstand konnte nicht geladen werden! Unbekannte Entität '%s' im gespeicherten Spiel gefunden! Der Spielstand ist möglicherweise nicht mit der aktuell installierten Version der Mods kompatibel!",
+	"vcmi.server.errors.saveFile.unknownEntity" : "Spielstand konnte nicht geladen werden! Unbekannte Entität '%s' im gespeicherten Spiel gefunden! Der Spielstand ist möglicherweise nicht mit der aktuell installierten Version der Mods kompatibel!",
 	"vcmi.server.errors.wrongIdentified"   : "Ihr wurdet als Spieler %s identifiziert, während %s erwartet wurde",
 	"vcmi.server.errors.notAllowed"   : "Ihr dürft diese Aktion nicht durchführen!",
 	

+ 1 - 1
Mods/vcmi/Content/config/hungarian.json

@@ -225,7 +225,7 @@
 	"vcmi.server.errors.existingProcess" : "Egy másik VCMI szerver folyamat fut. Kérjük, zárja be, mielőtt új játékot indítana.",
 	"vcmi.server.errors.modsToEnable"    : "{Az alábbi modok szükségesek}",
 	"vcmi.server.errors.modsToDisable"   : "{Az alábbi modokat le kell tiltani}",
-	"vcmi.server.errors.unknownEntity" : "Nem sikerült betölteni a mentést! Ismeretlen entitás '%s' található a mentett játékban! A mentés nem kompatibilis a jelenleg telepített modverziókkal!",
+	"vcmi.server.errors.saveFile.unknownEntity" : "Nem sikerült betölteni a mentést! Ismeretlen entitás '%s' található a mentett játékban! A mentés nem kompatibilis a jelenleg telepített modverziókkal!",
 	"vcmi.server.errors.wrongIdentified"   : "Önt %s játékosként azonosították, miközben %s játékosra számítottak",
 	"vcmi.server.errors.notAllowed"   : "Nem engedélyezett művelet!",
 	

+ 1 - 1
Mods/vcmi/Content/config/italian.json

@@ -227,7 +227,7 @@
 	"vcmi.server.errors.existingProcess" : "Un altro processo del server VCMI è in esecuzione. Terminarlo prima di avviare una nuova partita.",
 	"vcmi.server.errors.modsToEnable"    : "{Le seguenti mod sono richieste}",
 	"vcmi.server.errors.modsToDisable"   : "{Le seguenti mod devono essere disattivate}",
-	"vcmi.server.errors.unknownEntity" : "Impossibile caricare il salvataggio! Entità sconosciuta '%s' trovata nel salvataggio! Il salvataggio potrebbe non essere compatibile con la versione attualmente installata delle mod!",
+	"vcmi.server.errors.saveFile.unknownEntity" : "Impossibile caricare il salvataggio! Entità sconosciuta '%s' trovata nel salvataggio! Il salvataggio potrebbe non essere compatibile con la versione attualmente installata delle mod!",
 	"vcmi.server.errors.wrongIdentified"   : "Sei stato identificato come giocatore %s mentre ci si aspettava %s",
 	"vcmi.server.errors.notAllowed"   : "Non ti è permesso eseguire questa azione!",
 	

+ 2 - 1
Mods/vcmi/Content/config/polish.json

@@ -250,7 +250,8 @@
 	"vcmi.server.errors.modsToDisable"   : "{Następujące mody muszą zostać wyłączone}",
 	"vcmi.server.errors.modDependencyLoop" : "Nie udało się wczytać moda {'%s'}!\n Być może znajduje się w pętli zależności",
 	"vcmi.server.errors.notAllowed" : "To działanie nie jest dozwolone!",
-	"vcmi.server.errors.unknownEntity" : "Nie udało się wczytać zapisu! Nieznany element '%s' znaleziony w pliku zapisu! Zapis może nie być zgodny z aktualnie zainstalowaną wersją modów!",
+	"vcmi.server.errors.saveFile.unknownEntity" : "Nie udało się wczytać zapisu! Nieznany element '%s' znaleziony w pliku zapisu! Zapis może nie być zgodny z aktualnie zainstalowaną wersją modów!",
+	"vcmi.server.errors.campOrMapFile.unknownEntity" : "Nie udało się wczytać pliku! Nieznany element '%s' znaleziony w pliku! Plik może nie być zgodny z aktualnie zainstalowaną wersją modów!",
 	"vcmi.server.errors.wrongIdentified" : "Zostałeś zidentyfikowany jako gracz %s natomiast powinieneś być %s",
 	
 	"vcmi.dimensionDoor.seaToLandError" : "Nie jest możliwa teleportacja przez drzwi wymiarów z wód na ląd i na odwrót.",

+ 1 - 1
Mods/vcmi/Content/config/portuguese.json

@@ -244,7 +244,7 @@
 	"vcmi.server.errors.existingProcess" : "Outro processo do servidor VCMI está em execução. Por favor, termine-o antes de iniciar um novo jogo.",
 	"vcmi.server.errors.modsToEnable"    : "{Os seguintes mods são necessários}",
 	"vcmi.server.errors.modsToDisable"   : "{Os seguintes mods devem ser desativados}",
-	"vcmi.server.errors.unknownEntity" : "Falha ao carregar o jogo salvo! Entidade desconhecida '%s' encontrada no jogo salvo! O jogo salvo pode não ser compatível com a versão atualmente instalada dos mods!",
+	"vcmi.server.errors.saveFile.unknownEntity" : "Falha ao carregar o jogo salvo! Entidade desconhecida '%s' encontrada no jogo salvo! O jogo salvo pode não ser compatível com a versão atualmente instalada dos mods!",
 	"vcmi.server.errors.wrongIdentified"   : "Você foi identificado como o jogador %s, mas esperava-se %s",
 	"vcmi.server.errors.notAllowed"   : "Você não tem permissão para realizar esta ação!",
 	

+ 1 - 1
Mods/vcmi/Content/config/russian.json

@@ -225,7 +225,7 @@
 	"vcmi.server.errors.existingProcess" : "Запущен другой процесс сервера VCMI. Пожалуйста, завершите его перед запуском новой игры.",
 	"vcmi.server.errors.modsToEnable"    : "{Требуемые моды для загрузки игры}",
 	"vcmi.server.errors.modsToDisable"   : "{Необходимо отключить следующие моды}",
-	"vcmi.server.errors.unknownEntity" : "Не удалось загрузить сохранение! В сохраненной игре обнаружен неизвестный объект '%s'! Возможно, сохранение несовместимо с текущей версией модов!",
+	"vcmi.server.errors.saveFile.unknownEntity" : "Не удалось загрузить сохранение! В сохраненной игре обнаружен неизвестный объект '%s'! Возможно, сохранение несовместимо с текущей версией модов!",
 	"vcmi.server.errors.wrongIdentified"   : "Вы были идентифицированы как игрок %s, ожидалось %s",
 	"vcmi.server.errors.notAllowed"   : "Вам запрещено выполнять данное действие!",
 	"vcmi.dimensionDoor.seaToLandError" : "Невозможно телепортироваться с моря на сушу или наоборот с помощью Двери Измерений.",

+ 1 - 1
Mods/vcmi/Content/config/spanish.json

@@ -76,7 +76,7 @@
 	"vcmi.server.errors.modsToEnable"    : "{Se requieren los siguientes mods}",
 	"vcmi.server.errors.modsToDisable"   : "{Deben desactivarse los siguientes mods}",
 	"vcmi.server.confirmReconnect"       : "¿Quieres reconectar a la última sesión?",
-	"vcmi.server.errors.unknownEntity" : "Error al cargar la partida guardada. ¡Se encontró una entidad desconocida '%s' en la partida guardada! Es posible que la partida no sea compatible con la versión actualmente instalada de los mods.",
+	"vcmi.server.errors.saveFile.unknownEntity" : "Error al cargar la partida guardada. ¡Se encontró una entidad desconocida '%s' en la partida guardada! Es posible que la partida no sea compatible con la versión actualmente instalada de los mods.",
 
 	"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",

+ 1 - 1
Mods/vcmi/Content/config/swedish.json

@@ -249,7 +249,7 @@
 	"vcmi.server.errors.existingProcess"  : "En annan VCMI-serverprocess är igång. Vänligen avsluta den innan du startar ett nytt spel.",
 	"vcmi.server.errors.modsToEnable"     : "{Följande modd(ar) krävs}",
 	"vcmi.server.errors.modsToDisable"    : "{Följande modd(ar) måste inaktiveras}",
-	"vcmi.server.errors.unknownEntity"    : "Misslyckades med att ladda sparat spel! Okänd enhet '%s' hittades i sparat spel! Sparningen kanske inte är kompatibel med den aktuella versionen av moddarna!",
+	"vcmi.server.errors.saveFile.unknownEntity"    : "Misslyckades med att ladda sparat spel! Okänd enhet '%s' hittades i sparat spel! Sparningen kanske inte är kompatibel med den aktuella versionen av moddarna!",
 	"vcmi.server.errors.wrongIdentified"  : "Du identifierades som spelare %s när du förväntade dig %s",
 	"vcmi.server.errors.notAllowed"       : "Du får inte utföra denna åtgärd!",
 

+ 1 - 1
Mods/vcmi/Content/config/ukrainian.json

@@ -241,7 +241,7 @@
 	"vcmi.server.errors.existingProcess" : "Працює інший процес vcmiserver, будь ласка, спочатку завершіть його",
 	"vcmi.server.errors.modsToEnable"    : "{Потрібні модифікації для завантаження гри}",
 	"vcmi.server.errors.modsToDisable"   : "{Модифікації що мають бути вимкнені}",
-	"vcmi.server.errors.unknownEntity" : "Не вдалося завантажити гру! У збереженій грі знайдено невідомий об'єкт '%s'! Це збереження може бути несумісним зі встановленою версією модифікацій!",
+	"vcmi.server.errors.saveFile.unknownEntity" : "Не вдалося завантажити гру! У збереженій грі знайдено невідомий об'єкт '%s'! Це збереження може бути несумісним зі встановленою версією модифікацій!",
 	"vcmi.server.errors.wrongIdentified"   : "Ви були ідентифіковані як гравець %s, хоча очікували %s",
 	"vcmi.server.errors.notAllowed"   : "Ви не можете виконати цю дію!",
 	

+ 1 - 1
Mods/vcmi/Content/config/vietnamese.json

@@ -249,7 +249,7 @@
 	"vcmi.server.errors.existingProcess" : "Một chương trình máy chủ VCMI khác đang chạy. Hãy đóng nó trước khi bắt đầu một trò chơi mới.",
 	"vcmi.server.errors.modsToEnable"    : "{Các mod sau đây là bắt buộc}",
 	"vcmi.server.errors.modsToDisable"   : "{Bạn phải tắt các mod sau đây}",
-	"vcmi.server.errors.unknownEntity" : "Không tải được tệp tin đã lưu! Có lỗi chưa xác định trong tệp tin đã lưu '%s'! Tệp tin có thể không tương thích với phiên bản mod hiện đang cài đặt!",
+	"vcmi.server.errors.saveFile.unknownEntity" : "Không tải được tệp tin đã lưu! Có lỗi chưa xác định trong tệp tin đã lưu '%s'! Tệp tin có thể không tương thích với phiên bản mod hiện đang cài đặt!",
 	"vcmi.server.errors.wrongIdentified"   : "Bạn được chỉ định là người chơi %s trong khi bạn muốn %s",
 	"vcmi.server.errors.notAllowed"   : "Bạn không được phép thực hiện hành động này!",
 	

+ 3 - 13
client/CServerHandler.cpp

@@ -569,24 +569,14 @@ bool CServerHandler::validateGameStart(bool allowOnlyAI) const
 	catch(ModIncompatibility & e)
 	{
 		logGlobal->warn("Incompatibility exception during start scenario: %s", e.what());
-		std::string errorMsg;
-		if(!e.whatMissing().empty())
-		{
-			errorMsg += LIBRARY->generaltexth->translate("vcmi.server.errors.modsToEnable") + '\n';
-			errorMsg += e.whatMissing();
-		}
-		if(!e.whatExcessive().empty())
-		{
-			errorMsg += LIBRARY->generaltexth->translate("vcmi.server.errors.modsToDisable") + '\n';
-			errorMsg += e.whatExcessive();
-		}
-		showServerError(errorMsg);
+
+		showServerError(e.getFullErrorMsg());
 		return false;
 	}
 	catch(std::exception & e)
 	{
 		logGlobal->error("Exception during startScenario: %s", e.what());
-		showServerError( std::string("Unable to start map! Reason: ") + e.what());
+		showServerError(std::string("Unable to start map!\nReason: ") + e.what());
 		return false;
 	}
 

+ 1 - 1
client/NetPacksLobbyClient.cpp

@@ -146,7 +146,6 @@ void ApplyOnLobbyHandlerNetPackVisitor::visitLobbyRestartGame(LobbyRestartGame &
 
 void ApplyOnLobbyHandlerNetPackVisitor::visitLobbyPrepareStartGame(LobbyPrepareStartGame & pack)
 {
-	handler.client = std::make_unique<CClient>();
 	handler.logicConnection->enterLobbyConnectionMode();
 }
 
@@ -159,6 +158,7 @@ void ApplyOnLobbyHandlerNetPackVisitor::visitLobbyStartGame(LobbyStartGame & pac
 		handler.si = pack.initializedStartInfo;
 		handler.si->mode = modeBackup;
 	}
+	handler.client = std::make_unique<CClient>();
 	handler.startGameplay(pack.initializedGameState);
 }
 

+ 3 - 3
lib/mapObjectConstructors/CObjectClassesHandler.cpp

@@ -408,9 +408,9 @@ TObjectTypeHandler CObjectClassesHandler::getHandlerFor(const std::string & scop
 			return object->objectTypeHandlers.at(subID.value());
 	}
 
-	std::string errorString = "Failed to find object of type " + type + "::" + subtype;
-	logGlobal->error(errorString);
-	throw std::runtime_error(errorString);
+	std::string objectType = type + "::" + subtype;
+	logGlobal->error("Failed to find object of type %s", objectType);
+	throw IdentifierResolutionException(objectType);
 }
 
 TObjectTypeHandler CObjectClassesHandler::getHandlerFor(CompoundMapObjectID compoundIdentifier) const

+ 19 - 0
lib/modding/ModIncompatibility.h

@@ -9,6 +9,9 @@
  */
 #pragma once
 
+#include "../lib/texts/CGeneralTextHandler.h"
+#include "GameLibrary.h"
+
 VCMI_LIB_NAMESPACE_BEGIN
 
 class DLL_LINKAGE ModIncompatibility: public std::exception
@@ -49,6 +52,22 @@ public:
 		return messageExcessiveMods;
 	}
 
+	std::string getFullErrorMsg() const noexcept
+	{
+		std::string errorMsg;
+		if(!messageMissingMods.empty())
+		{
+			errorMsg += LIBRARY->generaltexth->translate("vcmi.server.errors.modsToEnable") + '\n';
+			errorMsg += messageMissingMods;
+		}
+		if(!messageExcessiveMods.empty())
+		{
+			errorMsg += LIBRARY->generaltexth->translate("vcmi.server.errors.modsToDisable") + '\n';
+			errorMsg += messageExcessiveMods;
+		}
+		return errorMsg;
+	}
+
 private:
 	std::string messageMissingMods;
 	std::string messageExcessiveMods;

+ 11 - 1
mapeditor/mainwindow.cpp

@@ -467,9 +467,19 @@ bool MainWindow::openMap(const QString & filenameSelect)
 	catch(const ModIncompatibility & e)
 	{
 		assert(e.whatExcessive().empty());
-		QMessageBox::warning(this, tr("Mods are required"), QString::fromStdString(e.whatMissing()));
+		auto qstrError = QString::fromStdString(e.getFullErrorMsg()).remove('{').remove('}');
+		QMessageBox::warning(this, tr("Mods are required"), qstrError);
 		return false;
 	}
+	catch(const IdentifierResolutionException & e)
+	{
+		MetaString errorMsg;
+		errorMsg.appendTextID("vcmi.server.errors.campOrMapFile.unknownEntity");
+		errorMsg.replaceRawString(e.identifierName);
+		QMessageBox::critical(this, tr("Failed to open map"), QString::fromStdString(errorMsg.toString()));
+		return false;
+	}
+
 	catch(const std::exception & e)
 	{
 		QMessageBox::critical(this, tr("Failed to open map"), tr(e.what()));

+ 63 - 50
server/CVCMIServer.cpp

@@ -230,9 +230,6 @@ bool CVCMIServer::prepareToStartGame()
 	Load::Progress current(1);
 	progressTracking.include(current);
 
-	if (lobbyProcessor)
-		lobbyProcessor->sendGameStarted();
-
 	auto progressTrackingThread = std::thread([this, &progressTracking]()
 	{
 		setThreadName("progressTrackingThread");
@@ -252,43 +249,72 @@ bool CVCMIServer::prepareToStartGame()
 		}
 	});
 
-	gh = std::make_shared<CGameHandler>(*this);
-	switch(si->mode)
+	auto newGH = std::make_shared<CGameHandler>(*this);
+	bool started = false;
+	try
 	{
-	case EStartMode::CAMPAIGN:
-		logNetwork->info("Preparing to start new campaign");
-		si->startTime = std::time(nullptr);
-		si->fileURI = mi->fileURI;
-		si->campState->setCurrentMap(campaignMap);
-		si->campState->setCurrentMapBonus(campaignBonus);
-		gh->init(si.get(), progressTracking);
-		break;
-
-	case EStartMode::NEW_GAME:
-		logNetwork->info("Preparing to start new game");
-		si->startTime = std::time(nullptr);
-		si->fileURI = mi->fileURI;
-		gh->init(si.get(), progressTracking);
-		break;
-
-	case EStartMode::LOAD_GAME:
-		logNetwork->info("Preparing to start loaded game");
-		if(!loadSavedGame(*si))
+		switch(si->mode)
 		{
-			current.finish();
-			progressTrackingThread.join();
-			return false;
+		case EStartMode::CAMPAIGN:
+			logNetwork->info("Preparing to start new campaign");
+			si->startTime = std::time(nullptr);
+			si->fileURI = mi->fileURI;
+			si->campState->setCurrentMap(campaignMap);
+			si->campState->setCurrentMapBonus(campaignBonus);
+			newGH->init(si.get(), progressTracking);	// may throw
+			started = true;
+			break;
+		case EStartMode::NEW_GAME:
+			logNetwork->info("Preparing to start new game");
+			si->startTime = std::time(nullptr);
+			si->fileURI = mi->fileURI;
+			newGH->init(si.get(), progressTracking);	// may throw
+			started = true;
+			break;
+
+		case EStartMode::LOAD_GAME:
+			logNetwork->info("Preparing to start loaded game");
+			if(loadSavedGame(*newGH, *si))
+				started = true;
+			break;
+		default:
+			logNetwork->error("Wrong mode in StartInfo!");
+			assert(0);
+			break;
 		}
-		break;
-	default:
-		logNetwork->error("Wrong mode in StartInfo!");
-		assert(0);
-		break;
 	}
-
+	catch(const ModIncompatibility & e)
+	{
+		logGlobal->error("Failed to launch game: %s", e.what());
+		announceMessage(e.getFullErrorMsg());
+	}
+	catch(const IdentifierResolutionException & e)
+	{
+		logGlobal->error("Failed to launch game: %s", e.what());
+		MetaString errorMsg;
+		errorMsg.appendTextID("vcmi.server.errors.campOrMapFile.unknownEntity");
+		errorMsg.replaceRawString(e.identifierName);
+		announceMessage(errorMsg);
+	}
+	catch(const std::exception & e)
+	{
+		logGlobal->error("Failed to launch game: %s", e.what());
+		auto str = MetaString::createFromTextID("vcmi.broadcast.failedLoadGame");
+		str.appendRawString(":\n");
+		str.appendRawString(e.what());
+		announceMessage(str);
+	}
 	current.finish();
 	progressTrackingThread.join();
 
+	if (!started)
+		return false;
+
+	gh = std::move(newGH);
+
+	if(lobbyProcessor)
+		lobbyProcessor->sendGameStarted();
+
 	return true;
 }
 
@@ -1066,36 +1092,23 @@ INetworkServer & CVCMIServer::getNetworkServer()
 	return *networkServer;
 }
 
-bool CVCMIServer::loadSavedGame(const StartInfo &info)
+bool CVCMIServer::loadSavedGame(CGameHandler & handler, const StartInfo & info)
 {
 	try
 	{
-		gh->load(info);
+		handler.load(info);
 	}
 	catch(const ModIncompatibility & e)
 	{
 		logGlobal->error("Failed to load game: %s", e.what());
-		MetaString errorMsg;
-		if(!e.whatMissing().empty())
-		{
-			errorMsg.appendTextID("vcmi.server.errors.modsToEnable");
-			errorMsg.appendRawString("\n");
-			errorMsg.appendRawString(e.whatMissing());
-		}
-		if(!e.whatExcessive().empty())
-		{
-			errorMsg.appendTextID("vcmi.server.errors.modsToDisable");
-			errorMsg.appendRawString("\n");
-			errorMsg.appendRawString(e.whatExcessive());
-		}
-		announceMessage(errorMsg);
+		announceMessage(e.getFullErrorMsg());
 		return false;
 	}
 	catch(const IdentifierResolutionException & e)
 	{
 		logGlobal->error("Failed to load game: %s", e.what());
 		MetaString errorMsg;
-		errorMsg.appendTextID("vcmi.server.errors.unknownEntity");
+		errorMsg.appendTextID("vcmi.server.errors.saveFile.unknownEntity");
 		errorMsg.replaceRawString(e.identifierName);
 		announceMessage(errorMsg);
 		return false;

+ 1 - 1
server/CVCMIServer.h

@@ -55,7 +55,7 @@ class CVCMIServer : public LobbyInfo, public INetworkServerListener, public INet
 	bool runByClient;
 
 
-	bool loadSavedGame(const StartInfo &info);
+	bool loadSavedGame(CGameHandler & handler, const StartInfo & info);
 public:
 
 	// IGameServer impl