소스 검색

Added information on mod loading failure to inform player on broken mods

Ivan Savenko 9 달 전
부모
커밋
485361939a
4개의 변경된 파일42개의 추가작업 그리고 1개의 파일을 삭제
  1. 1 0
      Mods/vcmi/Content/config/english.json
  2. 23 1
      clientapp/EntryPoint.cpp
  3. 12 0
      lib/modding/IdentifierStorage.cpp
  4. 6 0
      lib/modding/IdentifierStorage.h

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

@@ -222,6 +222,7 @@
 
 	"vcmi.client.errors.invalidMap" : "{Invalid map or campaign}\n\nFailed to start game! Selected map or campaign might be invalid or corrupted. Reason:\n%s",
 	"vcmi.client.errors.missingCampaigns" : "{Missing data files}\n\nCampaigns data files were not found! You may be using incomplete or corrupted Heroes 3 data files. Please reinstall game data.",
+	"vcmi.client.errors.modLoadingFailure" : "{Mod loading failure}\n\nCritical issues found when loading mods! Game may not work correctly or crash! Please update or disable following mods:\n\n",
 	"vcmi.server.errors.disconnected" : "{Network Error}\n\nConnection to game server has been lost!",
 	"vcmi.server.errors.playerLeft" : "{Player Left}\n\n%s player have disconnected from the game!", //%s -> player color
 	"vcmi.server.errors.existingProcess" : "Another VCMI server process is running. Please terminate it before starting a new game.",

+ 23 - 1
clientapp/EntryPoint.cpp

@@ -38,7 +38,11 @@
 #include "../lib/ExceptionsCommon.h"
 #include "../lib/filesystem/Filesystem.h"
 #include "../lib/logging/CBasicLogConfigurator.h"
+#include "../lib/modding/IdentifierStorage.h"
+#include "../lib/modding/CModHandler.h"
+#include "../lib/modding/ModDescription.h"
 #include "../lib/texts/CGeneralTextHandler.h"
+#include "../lib/texts/MetaString.h"
 #include "../lib/VCMI_Lib.h"
 #include "../lib/VCMIDirs.h"
 
@@ -71,7 +75,7 @@ static void mainLoop();
 
 static CBasicLogConfigurator *logConfig;
 
-void init()
+static void init()
 {
 	CStopWatch tmh;
 	try
@@ -92,6 +96,23 @@ void init()
 	//commandController.processCommand("convert txt", false);
 }
 
+static void checkForModLoadingFailure()
+{
+	const auto & brokenMods = VLC->identifiersHandler->getModsWithFailedRequests();
+	if (!brokenMods.empty())
+	{
+		MetaString messageText;
+		messageText.appendTextID("vcmi.client.errors.modLoadingFailure");
+
+		for (const auto & modID : brokenMods)
+		{
+			messageText.appendRawString(VLC->modh->getModInfo(modID).getName());
+			messageText.appendEOL();
+		}
+		CInfoWindow::showInfoDialog(messageText.toString(), {});
+	}
+}
+
 static void prog_version()
 {
 	printf("%s\n", GameConstants::VCMI_VERSION.c_str());
@@ -386,6 +407,7 @@ int main(int argc, char * argv[])
 
 	if(!settings["session"]["headless"].Bool())
 	{
+		checkForModLoadingFailure();
 		mainLoop();
 	}
 	else

+ 12 - 0
lib/modding/IdentifierStorage.cpp

@@ -442,6 +442,7 @@ bool CIdentifierStorage::resolveIdentifier(const ObjectCallback & request) const
 	}
 
 	// error found. Try to generate some debug info
+	failedRequests.push_back(request);
 	showIdentifierResolutionErrorDetails(request);
 	return false;
 }
@@ -494,4 +495,15 @@ void CIdentifierStorage::debugDumpIdentifiers()
 	}
 }
 
+std::vector<std::string> CIdentifierStorage::getModsWithFailedRequests() const
+{
+	std::vector<std::string> result;
+
+	for (const auto & request : failedRequests)
+		if (!vstd::contains(result, request.localScope))
+			result.push_back(request.localScope);
+
+	return result;
+}
+
 VCMI_LIB_NAMESPACE_END

+ 6 - 0
lib/modding/IdentifierStorage.h

@@ -58,6 +58,9 @@ class DLL_LINKAGE CIdentifierStorage
 	std::multimap<std::string, ObjectData> registeredObjects;
 	mutable std::vector<ObjectCallback> scheduledRequests;
 
+	/// All non-optional requests that have failed to resolve, for debug & error reporting
+	mutable std::vector<ObjectCallback> failedRequests;
+
 	ELoadingState state = ELoadingState::LOADING;
 
 	/// Helper method that dumps all registered identifier into log file
@@ -101,6 +104,9 @@ public:
 
 	/// called at the very end of loading to check for any missing ID's
 	void finalize();
+
+	/// Returns list of all mods, from which at least one identifier has failed to resolve
+	std::vector<std::string> getModsWithFailedRequests() const;
 };
 
 VCMI_LIB_NAMESPACE_END