Properly handle mod name conflicts
authorPerttu Ahola <celeron55@gmail.com>
Sat, 3 Dec 2011 01:32:30 +0000 (03:32 +0200)
committerPerttu Ahola <celeron55@gmail.com>
Sat, 3 Dec 2011 01:32:30 +0000 (03:32 +0200)
src/mods.cpp
src/server.cpp

index 285c4cbb927cd2d29bacda3453cd8bd3eeb70f96..db878d78b40b83634786a00215ed9d5df364c9a9 100644 (file)
@@ -21,8 +21,10 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include <queue>
 #include <fstream>
 #include <sstream>
+#include <map>
 #include "filesys.h"
 #include "strfnd.h"
+#include "log.h"
 
 // Get a dependency-sorted list of ModSpecs
 core::list<ModSpec> getMods(core::list<std::string> &modspaths)
@@ -31,6 +33,8 @@ core::list<ModSpec> getMods(core::list<std::string> &modspaths)
        std::queue<ModSpec> mods_satisfied;
        core::list<ModSpec> mods_unsorted;
        core::list<ModSpec> mods_sorted;
+       // name, path: For detecting name conflicts
+       std::map<std::string, std::string> mod_names;
        for(core::list<std::string>::Iterator i = modspaths.begin();
                        i != modspaths.end(); i++){
                std::string modspath = *i;
@@ -40,6 +44,19 @@ core::list<ModSpec> getMods(core::list<std::string> &modspaths)
                                continue;
                        std::string modname = dirlist[j].name;
                        std::string modpath = modspath + DIR_DELIM + modname;
+                       // Detect mod name conflicts
+                       {
+                               std::map<std::string, std::string>::const_iterator i;
+                               i = mod_names.find(modname);
+                               if(i != mod_names.end()){
+                                       std::string s;
+                                       infostream<<"WARNING: Mod name conflict detected: "
+                                                       <<std::endl
+                                                       <<"Already loaded: "<<i->second<<std::endl
+                                                       <<"Will not load: "<<modpath<<std::endl;
+                                       continue;
+                               }
+                       }
                        std::set<std::string> depends;
                        std::ifstream is((modpath+DIR_DELIM+"depends.txt").c_str(),
                                        std::ios_base::binary);
@@ -54,6 +71,7 @@ core::list<ModSpec> getMods(core::list<std::string> &modspaths)
                        mods_unsorted.push_back(spec);
                        if(depends.empty())
                                mods_satisfied.push(spec);
+                       mod_names[modname] = modpath;
                }
        }
        // Sort by depencencies
index e4052015d1c973b186b31a15737d456da76d29cd..032b57e3ca003c5db33adb35e99701e9f99d8323 100644 (file)
@@ -881,9 +881,9 @@ Server::Server(
        std::string builtinpath = porting::path_data + DIR_DELIM + "builtin.lua";
 
        // Add default global mod search path
-       m_modspaths.push_back(porting::path_data + DIR_DELIM + "mods");
+       m_modspaths.push_front(porting::path_data + DIR_DELIM + "mods");
        // Add world mod search path
-       m_modspaths.push_back(mapsavedir + DIR_DELIM + "mods");
+       m_modspaths.push_front(mapsavedir + DIR_DELIM + "mods");
 
        // Initialize scripting