Add minetest.get_modnames() to Lua API
authorMatthew I <matttpt@gmail.com>
Sun, 22 Jul 2012 01:29:37 +0000 (21:29 -0400)
committerPerttu Ahola <celeron55@gmail.com>
Sun, 22 Jul 2012 10:36:03 +0000 (13:36 +0300)
src/scriptapi.cpp
src/server.cpp
src/server.h

index 17483ec1630888e06cb50974e79252b7de8113c6..a72e66b4f315f9bc84158f916986341e2c1a92e1 100644 (file)
@@ -4461,6 +4461,60 @@ static int l_get_modpath(lua_State *L)
        return 1;
 }
 
+// get_modnames()
+// the returned list is sorted alphabetically for you
+static int l_get_modnames(lua_State *L)
+{
+       // Get a list of mods
+       core::list<std::string> mods_unsorted, mods_sorted;
+       get_server(L)->getModNames(mods_unsorted);
+
+       // Take unsorted items from mods_unsorted and sort them into
+       // mods_sorted; not great performance but the number of mods on a
+       // server will likely be small.
+       for(core::list<std::string>::Iterator i = mods_unsorted.begin();
+           i != mods_unsorted.end(); i++)
+       {
+               bool added = false;
+               for(core::list<std::string>::Iterator x = mods_sorted.begin();
+                   x != mods_unsorted.end(); x++)
+               {
+                       // I doubt anybody using Minetest will be using
+                       // anything not ASCII based :)
+                       if((*i).compare(*x) <= 0)
+                       {
+                               mods_sorted.insert_before(x, *i);
+                               added = true;
+                               break;
+                       }
+               }
+               if(!added)
+                       mods_sorted.push_back(*i);
+       }
+
+       // Get the table insertion function from Lua.
+       lua_getglobal(L, "table");
+       lua_getfield(L, -1, "insert");
+       int insertion_func = lua_gettop(L);
+
+       // Package them up for Lua
+       lua_newtable(L);
+       int new_table = lua_gettop(L);
+       core::list<std::string>::Iterator i = mods_sorted.begin();
+       while(i != mods_sorted.end())
+       {
+               lua_pushvalue(L, insertion_func);
+               lua_pushvalue(L, new_table);
+               lua_pushstring(L, (*i).c_str());
+               if(lua_pcall(L, 2, 0, 0) != 0)
+               {
+                       script_error(L, "error: %s", lua_tostring(L, -1));
+               }
+               i++;
+       }
+       return 1;
+}
+
 // get_worldpath()
 static int l_get_worldpath(lua_State *L)
 {
@@ -4630,6 +4684,7 @@ static const struct luaL_Reg minetest_f [] = {
        {"get_hit_params", l_get_hit_params},
        {"get_current_modname", l_get_current_modname},
        {"get_modpath", l_get_modpath},
+       {"get_modnames", l_get_modnames},
        {"get_worldpath", l_get_worldpath},
        {"sound_play", l_sound_play},
        {"sound_stop", l_sound_stop},
index a44a6a2eedf6c62d8034f0b2834f7632184d77b5..2a6c6054f56bca4bc5c50cce4271732ae8fec108 100644 (file)
@@ -4531,6 +4531,13 @@ const ModSpec* Server::getModSpec(const std::string &modname)
        }
        return NULL;
 }
+void Server::getModNames(core::list<std::string> &modlist)
+{
+       for(core::list<ModSpec>::Iterator i = m_mods.begin(); i != m_mods.end(); i++)
+       {
+               modlist.push_back((*i).name);
+       }
+}
 std::string Server::getBuiltinLuaPath()
 {
        return porting::path_share + DIR_DELIM + "builtin";
index 36c243ccdcf968b767a280b4dfd3280722652c01..f170cf7e11908903020569187599084564fc58d0 100644 (file)
@@ -556,6 +556,7 @@ public:
        IWritableCraftDefManager* getWritableCraftDefManager();
 
        const ModSpec* getModSpec(const std::string &modname);
+       void getModNames(core::list<std::string> &modlist);
        std::string getBuiltinLuaPath();
        
        std::string getWorldPath(){ return m_path_world; }