Browse Source

Updated love.filesystem's C library loader for require to look in paths added via love.filesystem.mount, when in fused mode

Alex Szpakowski 11 years ago
parent
commit
a13fd761cc

+ 10 - 0
src/modules/filesystem/physfs/Filesystem.cpp

@@ -397,6 +397,16 @@ std::string Filesystem::getSourceBaseDirectory() const
 	return game_source.substr(0, base_end_pos);
 }
 
+std::string Filesystem::getRealDirectory(const char *filename) const
+{
+	const char *dir = PHYSFS_getRealDir(filename);
+
+	if (dir == nullptr)
+		throw love::Exception("File does not exist.");
+
+	return std::string(dir);
+}
+
 bool Filesystem::exists(const char *file) const
 {
 	return PHYSFS_exists(file);

+ 5 - 0
src/modules/filesystem/physfs/Filesystem.h

@@ -166,6 +166,11 @@ public:
 	 **/
 	std::string getSourceBaseDirectory() const;
 
+	/**
+	 * Gets the real directory path containing the file.
+	 **/
+	std::string getRealDirectory(const char *filename) const;
+
 	/**
 	 * Checks whether a file exists in the current search path
 	 * or not.

+ 25 - 3
src/modules/filesystem/physfs/wrap_Filesystem.cpp

@@ -526,9 +526,31 @@ int extloader(lua_State *L)
 
 	tokenized_name += library_extension();
 
-	void *handle = SDL_LoadObject((std::string(instance->getAppdataDirectory()) + LOVE_PATH_SEPARATOR LOVE_APPDATA_FOLDER LOVE_PATH_SEPARATOR + tokenized_name).c_str());
-	if (!handle && instance->isFused())
-		handle = SDL_LoadObject((std::string(instance->getSaveDirectory()) + LOVE_PATH_SEPARATOR + tokenized_name).c_str());
+	void *handle = nullptr;
+
+	// If the game is fused, try looking for the DLL in the game's read paths.
+	if (instance->isFused())
+	{
+		try
+		{
+			std::string dir = instance->getRealDirectory(tokenized_name.c_str());
+
+			// We don't want to look in the game's source, because it can be a
+			// zip sometimes and a folder other times.
+			if (dir.find(instance->getSource()) == std::string::npos)
+				handle = SDL_LoadObject((dir + LOVE_PATH_SEPARATOR + tokenized_name).c_str());
+		}
+		catch (love::Exception &)
+		{
+			// Nothing...
+		}
+	}
+
+	if (!handle)
+	{
+		std::string path = std::string(instance->getAppdataDirectory()) + LOVE_PATH_SEPARATOR LOVE_APPDATA_FOLDER LOVE_PATH_SEPARATOR + tokenized_name;
+		handle = SDL_LoadObject(path.c_str());
+	}
 
 	if (!handle)
 	{