瀏覽代碼

fixes #1237 - if server savegame entry is missing it will be created in "update mode".

Ivan Savenko 12 年之前
父節點
當前提交
3943c10f1a

+ 12 - 2
client/Client.cpp

@@ -230,8 +230,18 @@ void CClient::loadGame( const std::string & fname )
 	CStopWatch tmh;
 	try
 	{
-		auto clientSaveName = CResourceHandler::get()->getResourceName(ResourceID(fname, EResType::CLIENT_SAVEGAME));
-		auto controlServerSaveName = CResourceHandler::get()->getResourceName(ResourceID(fname, EResType::SERVER_SAVEGAME));
+		std::string clientSaveName = CResourceHandler::get()->getResourceName(ResourceID(fname, EResType::CLIENT_SAVEGAME));
+		std::string controlServerSaveName;
+
+		if (CResourceHandler::get()->existsResource(ResourceID(fname, EResType::SERVER_SAVEGAME)))
+		{
+			controlServerSaveName = CResourceHandler::get()->getResourceName(ResourceID(fname, EResType::SERVER_SAVEGAME));
+		}
+		else// create entry for server savegame. Triggered if save was made after launch and not yet present in res handler
+		{
+			controlServerSaveName = clientSaveName.substr(0, clientSaveName.find_last_of(".")) + ".vsgm1";
+			CResourceHandler::get()->createResource(controlServerSaveName, true);
+		}
 
 		if(clientSaveName.empty())
 			throw std::runtime_error("Cannot open client part of " + fname);

+ 3 - 2
lib/filesystem/CFilesystemLoader.cpp

@@ -39,14 +39,15 @@ std::string CFilesystemLoader::getOrigin() const
 	return baseDirectory;
 }
 
-bool CFilesystemLoader::createEntry(std::string filename)
+bool CFilesystemLoader::createEntry(std::string filename, bool update)
 {
 	ResourceID res(filename);
 	if (fileList.find(res) != fileList.end())
 		return false;
 
 	fileList[res] = filename;
-	std::ofstream newfile (baseDirectory + "/" + filename);
+	if (!update)
+		std::ofstream newfile (baseDirectory + "/" + filename);
 	return true;
 }
 

+ 1 - 1
lib/filesystem/CFilesystemLoader.h

@@ -39,7 +39,7 @@ public:
 	bool existsEntry(const std::string & resourceName) const override;
 	boost::unordered_map<ResourceID, std::string> getEntries() const override;
 	std::string getOrigin() const override;
-	bool createEntry(std::string filename) override;
+	bool createEntry(std::string filename, bool update) override;
 
 private:
 	/** The base directory which is scanned and indexed. */

+ 9 - 2
lib/filesystem/CResourceLoader.cpp

@@ -137,7 +137,7 @@ bool CResourceLoader::existsResource(const ResourceID & resourceIdent) const
 	return resources.find(resourceIdent) != resources.end();
 }
 
-bool CResourceLoader::createResource(std::string URI)
+bool CResourceLoader::createResource(std::string URI, bool update)
 {
 	std::string filename = URI;
 	boost::to_upper(URI);
@@ -148,9 +148,16 @@ bool CResourceLoader::createResource(std::string URI)
 			// remove loader prefix from filename
 			filename = filename.substr(entry.prefix.size());
 			if (!entry.loader->createEntry(filename))
-				return false; //or continue loop?
+				continue;
 
 			resources[ResourceID(URI)].push_back(ResourceLocator(entry.loader.get(), filename));
+
+			// Check if resource was created successfully. Possible reasons for this to fail
+			// a) loader failed to create resource (e.g. read-only FS)
+			// b) in update mode, call with filename that does not exists
+			assert(load(ResourceID(URI)));
+
+			return true;
 		}
 	}
 	return false;

+ 2 - 1
lib/filesystem/CResourceLoader.h

@@ -294,9 +294,10 @@ public:
 	 * File case will be same as in URI
 	 *
 	 * @param URI file to create
+	 * @param update if true - this file is already present but not yet known by res handler
 	 * @return true on success, false if resource exists or on error
 	 */
-	bool createResource(std::string URI);
+	bool createResource(std::string URI, bool update = false);
 
 	/**
 	 * Adds a simple resource loader to the loaders list and its entries to the resources list.

+ 1 - 1
lib/filesystem/ISimpleResourceLoader.h

@@ -67,7 +67,7 @@ public:
 	 *
 	 * @returns true if new file was created, false on error or if file already exists
 	 */
-	virtual bool createEntry(std::string filename)
+	virtual bool createEntry(std::string filename, bool update = false)
 	{
 		return false;
 	}