3 Copyright (C) 2013 sapier
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU Lesser General Public License as published by
7 the Free Software Foundation; either version 2.1 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public License along
16 with this program; if not, write to the Free Software Foundation, Inc.,
17 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 #include "lua_api/l_mainmenu.h"
21 #include "lua_api/l_internal.h"
22 #include "common/c_content.h"
23 #include "cpp_api/s_async.h"
24 #include "guiEngine.h"
25 #include "guiMainMenu.h"
26 #include "guiKeyChangeMenu.h"
27 #include "guiFileSelectMenu.h"
32 #include "convert_json.h"
33 #include "serverlist.h"
36 #include "EDriverTypes.h"
38 #include <IFileArchive.h>
39 #include <IFileSystem.h>
41 /******************************************************************************/
42 std::string ModApiMainMenu::getTextData(lua_State *L, std::string name)
44 lua_getglobal(L, "gamedata");
46 lua_getfield(L, -1, name.c_str());
51 return luaL_checkstring(L, -1);
54 /******************************************************************************/
55 int ModApiMainMenu::getIntegerData(lua_State *L, std::string name,bool& valid)
57 lua_getglobal(L, "gamedata");
59 lua_getfield(L, -1, name.c_str());
61 if(lua_isnil(L, -1)) {
67 return luaL_checkinteger(L, -1);
70 /******************************************************************************/
71 int ModApiMainMenu::getBoolData(lua_State *L, std::string name,bool& valid)
73 lua_getglobal(L, "gamedata");
75 lua_getfield(L, -1, name.c_str());
77 if(lua_isnil(L, -1)) {
83 return lua_toboolean(L, -1);
86 /******************************************************************************/
87 int ModApiMainMenu::l_update_formspec(lua_State *L)
89 GUIEngine* engine = getGuiEngine(L);
90 sanity_check(engine != NULL);
92 if (engine->m_startgame)
96 std::string formspec(luaL_checkstring(L, 1));
98 if (engine->m_formspecgui != 0) {
99 engine->m_formspecgui->setForm(formspec);
105 /******************************************************************************/
106 int ModApiMainMenu::l_start(lua_State *L)
108 GUIEngine* engine = getGuiEngine(L);
109 sanity_check(engine != NULL);
111 //update c++ gamedata from lua table
115 MainMenuData *data = engine->m_data;
117 data->selected_world = getIntegerData(L, "selected_world",valid) -1;
118 data->simple_singleplayer_mode = getBoolData(L,"singleplayer",valid);
119 data->do_reconnect = getBoolData(L, "do_reconnect", valid);
120 if (!data->do_reconnect) {
121 data->name = getTextData(L,"playername");
122 data->password = getTextData(L,"password");
123 data->address = getTextData(L,"address");
124 data->port = getTextData(L,"port");
126 data->serverdescription = getTextData(L,"serverdescription");
127 data->servername = getTextData(L,"servername");
129 //close menu next time
130 engine->m_startgame = true;
134 /******************************************************************************/
135 int ModApiMainMenu::l_close(lua_State *L)
137 GUIEngine* engine = getGuiEngine(L);
138 sanity_check(engine != NULL);
140 engine->m_kill = true;
144 /******************************************************************************/
145 int ModApiMainMenu::l_set_background(lua_State *L)
147 GUIEngine* engine = getGuiEngine(L);
148 sanity_check(engine != NULL);
150 std::string backgroundlevel(luaL_checkstring(L, 1));
151 std::string texturename(luaL_checkstring(L, 2));
153 bool tile_image = false;
155 unsigned int minsize = 16;
157 if (!lua_isnone(L, 3)) {
158 tile_image = lua_toboolean(L, 3);
161 if (!lua_isnone(L, 4)) {
162 minsize = lua_tonumber(L, 4);
165 if (backgroundlevel == "background") {
166 retval |= engine->setTexture(TEX_LAYER_BACKGROUND, texturename,
167 tile_image, minsize);
170 if (backgroundlevel == "overlay") {
171 retval |= engine->setTexture(TEX_LAYER_OVERLAY, texturename,
172 tile_image, minsize);
175 if (backgroundlevel == "header") {
176 retval |= engine->setTexture(TEX_LAYER_HEADER, texturename,
177 tile_image, minsize);
180 if (backgroundlevel == "footer") {
181 retval |= engine->setTexture(TEX_LAYER_FOOTER, texturename,
182 tile_image, minsize);
185 lua_pushboolean(L,retval);
189 /******************************************************************************/
190 int ModApiMainMenu::l_set_clouds(lua_State *L)
192 GUIEngine* engine = getGuiEngine(L);
193 sanity_check(engine != NULL);
195 bool value = lua_toboolean(L,1);
197 engine->m_clouds_enabled = value;
202 /******************************************************************************/
203 int ModApiMainMenu::l_get_textlist_index(lua_State *L)
205 // get_table_index accepts both tables and textlists
206 return l_get_table_index(L);
209 /******************************************************************************/
210 int ModApiMainMenu::l_get_table_index(lua_State *L)
212 GUIEngine* engine = getGuiEngine(L);
213 sanity_check(engine != NULL);
215 std::string tablename(luaL_checkstring(L, 1));
216 GUITable *table = engine->m_menu->getTable(tablename);
217 s32 selection = table ? table->getSelected() : 0;
220 lua_pushinteger(L, selection);
226 /******************************************************************************/
227 int ModApiMainMenu::l_get_worlds(lua_State *L)
229 std::vector<WorldSpec> worlds = getAvailableWorlds();
232 int top = lua_gettop(L);
233 unsigned int index = 1;
235 for (unsigned int i = 0; i < worlds.size(); i++)
237 lua_pushnumber(L,index);
240 int top_lvl2 = lua_gettop(L);
242 lua_pushstring(L,"path");
243 lua_pushstring(L,worlds[i].path.c_str());
244 lua_settable(L, top_lvl2);
246 lua_pushstring(L,"name");
247 lua_pushstring(L,worlds[i].name.c_str());
248 lua_settable(L, top_lvl2);
250 lua_pushstring(L,"gameid");
251 lua_pushstring(L,worlds[i].gameid.c_str());
252 lua_settable(L, top_lvl2);
254 lua_settable(L, top);
260 /******************************************************************************/
261 int ModApiMainMenu::l_get_games(lua_State *L)
263 std::vector<SubgameSpec> games = getAvailableGames();
266 int top = lua_gettop(L);
267 unsigned int index = 1;
269 for (unsigned int i = 0; i < games.size(); i++)
271 lua_pushnumber(L,index);
273 int top_lvl2 = lua_gettop(L);
275 lua_pushstring(L,"id");
276 lua_pushstring(L,games[i].id.c_str());
277 lua_settable(L, top_lvl2);
279 lua_pushstring(L,"path");
280 lua_pushstring(L,games[i].path.c_str());
281 lua_settable(L, top_lvl2);
283 lua_pushstring(L,"gamemods_path");
284 lua_pushstring(L,games[i].gamemods_path.c_str());
285 lua_settable(L, top_lvl2);
287 lua_pushstring(L,"name");
288 lua_pushstring(L,games[i].name.c_str());
289 lua_settable(L, top_lvl2);
291 lua_pushstring(L,"menuicon_path");
292 lua_pushstring(L,games[i].menuicon_path.c_str());
293 lua_settable(L, top_lvl2);
295 lua_pushstring(L,"addon_mods_paths");
297 int table2 = lua_gettop(L);
298 int internal_index=1;
299 for (std::set<std::string>::iterator iter = games[i].addon_mods_paths.begin();
300 iter != games[i].addon_mods_paths.end(); iter++) {
301 lua_pushnumber(L,internal_index);
302 lua_pushstring(L,(*iter).c_str());
303 lua_settable(L, table2);
306 lua_settable(L, top_lvl2);
307 lua_settable(L, top);
312 /******************************************************************************/
313 int ModApiMainMenu::l_get_modstore_details(lua_State *L)
315 const char *modid = luaL_checkstring(L, 1);
319 std::string url = "";
321 url = g_settings->get("modstore_details_url");
323 catch(SettingNotFoundException &e) {
328 size_t idpos = url.find("*");
330 url.insert(idpos,modid);
332 details = getModstoreUrl(url);
334 ModStoreModDetails current_mod = readModStoreModDetails(details);
336 if ( current_mod.valid) {
338 int top = lua_gettop(L);
340 lua_pushstring(L,"id");
341 lua_pushnumber(L,current_mod.id);
342 lua_settable(L, top);
344 lua_pushstring(L,"title");
345 lua_pushstring(L,current_mod.title.c_str());
346 lua_settable(L, top);
348 lua_pushstring(L,"basename");
349 lua_pushstring(L,current_mod.basename.c_str());
350 lua_settable(L, top);
352 lua_pushstring(L,"description");
353 lua_pushstring(L,current_mod.description.c_str());
354 lua_settable(L, top);
356 lua_pushstring(L,"author");
357 lua_pushstring(L,current_mod.author.username.c_str());
358 lua_settable(L, top);
360 lua_pushstring(L,"download_url");
361 lua_pushstring(L,current_mod.versions[0].file.c_str());
362 lua_settable(L, top);
364 lua_pushstring(L,"versions");
366 int versionstop = lua_gettop(L);
367 for (unsigned int i=0;i < current_mod.versions.size(); i++) {
368 lua_pushnumber(L,i+1);
370 int current_element = lua_gettop(L);
372 lua_pushstring(L,"date");
373 lua_pushstring(L,current_mod.versions[i].date.c_str());
374 lua_settable(L,current_element);
376 lua_pushstring(L,"download_url");
377 lua_pushstring(L,current_mod.versions[i].file.c_str());
378 lua_settable(L,current_element);
380 lua_settable(L,versionstop);
382 lua_settable(L, top);
384 lua_pushstring(L,"screenshot_url");
385 lua_pushstring(L,current_mod.titlepic.file.c_str());
386 lua_settable(L, top);
388 lua_pushstring(L,"license");
389 lua_pushstring(L,current_mod.license.shortinfo.c_str());
390 lua_settable(L, top);
392 lua_pushstring(L,"rating");
393 lua_pushnumber(L,current_mod.rating);
394 lua_settable(L, top);
405 /******************************************************************************/
406 int ModApiMainMenu::l_get_modstore_list(lua_State *L)
409 std::string url = "";
411 url = g_settings->get("modstore_listmods_url");
413 catch(SettingNotFoundException &e) {
418 mods = getModstoreUrl(url);
420 std::vector<ModStoreMod> moddata = readModStoreList(mods);
423 int top = lua_gettop(L);
424 unsigned int index = 1;
426 for (unsigned int i = 0; i < moddata.size(); i++)
428 if (moddata[i].valid) {
429 lua_pushnumber(L,index);
432 int top_lvl2 = lua_gettop(L);
434 lua_pushstring(L,"id");
435 lua_pushnumber(L,moddata[i].id);
436 lua_settable(L, top_lvl2);
438 lua_pushstring(L,"title");
439 lua_pushstring(L,moddata[i].title.c_str());
440 lua_settable(L, top_lvl2);
442 lua_pushstring(L,"basename");
443 lua_pushstring(L,moddata[i].basename.c_str());
444 lua_settable(L, top_lvl2);
446 lua_settable(L, top);
453 /******************************************************************************/
454 int ModApiMainMenu::l_get_favorites(lua_State *L)
456 std::string listtype = "local";
458 if (!lua_isnone(L,1)) {
459 listtype = luaL_checkstring(L,1);
462 std::vector<ServerListSpec> servers;
464 if(listtype == "online") {
465 servers = ServerList::getOnline();
467 servers = ServerList::getLocal();
471 int top = lua_gettop(L);
472 unsigned int index = 1;
474 for (unsigned int i = 0; i < servers.size(); i++)
477 lua_pushnumber(L,index);
480 int top_lvl2 = lua_gettop(L);
482 if (servers[i]["clients"].asString().size()) {
483 std::string clients_raw = servers[i]["clients"].asString();
485 int numbervalue = strtol(clients_raw.c_str(),&endptr,10);
487 if ((clients_raw != "") && (*endptr == 0)) {
488 lua_pushstring(L,"clients");
489 lua_pushnumber(L,numbervalue);
490 lua_settable(L, top_lvl2);
494 if (servers[i]["clients_max"].asString().size()) {
496 std::string clients_max_raw = servers[i]["clients_max"].asString();
498 int numbervalue = strtol(clients_max_raw.c_str(),&endptr,10);
500 if ((clients_max_raw != "") && (*endptr == 0)) {
501 lua_pushstring(L,"clients_max");
502 lua_pushnumber(L,numbervalue);
503 lua_settable(L, top_lvl2);
507 if (servers[i]["version"].asString().size()) {
508 lua_pushstring(L,"version");
509 std::string topush = servers[i]["version"].asString();
510 lua_pushstring(L,topush.c_str());
511 lua_settable(L, top_lvl2);
514 if (servers[i]["proto_min"].asString().size()) {
515 lua_pushstring(L,"proto_min");
516 lua_pushinteger(L,servers[i]["proto_min"].asInt());
517 lua_settable(L, top_lvl2);
520 if (servers[i]["proto_max"].asString().size()) {
521 lua_pushstring(L,"proto_max");
522 lua_pushinteger(L,servers[i]["proto_max"].asInt());
523 lua_settable(L, top_lvl2);
526 if (servers[i]["password"].asString().size()) {
527 lua_pushstring(L,"password");
528 lua_pushboolean(L,servers[i]["password"].asBool());
529 lua_settable(L, top_lvl2);
532 if (servers[i]["creative"].asString().size()) {
533 lua_pushstring(L,"creative");
534 lua_pushboolean(L,servers[i]["creative"].asBool());
535 lua_settable(L, top_lvl2);
538 if (servers[i]["damage"].asString().size()) {
539 lua_pushstring(L,"damage");
540 lua_pushboolean(L,servers[i]["damage"].asBool());
541 lua_settable(L, top_lvl2);
544 if (servers[i]["pvp"].asString().size()) {
545 lua_pushstring(L,"pvp");
546 lua_pushboolean(L,servers[i]["pvp"].asBool());
547 lua_settable(L, top_lvl2);
550 if (servers[i]["description"].asString().size()) {
551 lua_pushstring(L,"description");
552 std::string topush = servers[i]["description"].asString();
553 lua_pushstring(L,topush.c_str());
554 lua_settable(L, top_lvl2);
557 if (servers[i]["name"].asString().size()) {
558 lua_pushstring(L,"name");
559 std::string topush = servers[i]["name"].asString();
560 lua_pushstring(L,topush.c_str());
561 lua_settable(L, top_lvl2);
564 if (servers[i]["address"].asString().size()) {
565 lua_pushstring(L,"address");
566 std::string topush = servers[i]["address"].asString();
567 lua_pushstring(L,topush.c_str());
568 lua_settable(L, top_lvl2);
571 if (servers[i]["port"].asString().size()) {
572 lua_pushstring(L,"port");
573 std::string topush = servers[i]["port"].asString();
574 lua_pushstring(L,topush.c_str());
575 lua_settable(L, top_lvl2);
578 if (servers[i].isMember("ping")) {
579 float ping = servers[i]["ping"].asFloat();
580 lua_pushstring(L, "ping");
581 lua_pushnumber(L, ping);
582 lua_settable(L, top_lvl2);
585 lua_settable(L, top);
591 /******************************************************************************/
592 int ModApiMainMenu::l_delete_favorite(lua_State *L)
594 std::vector<ServerListSpec> servers;
596 std::string listtype = "local";
598 if (!lua_isnone(L,2)) {
599 listtype = luaL_checkstring(L,2);
602 if ((listtype != "local") &&
603 (listtype != "online"))
607 if(listtype == "online") {
608 servers = ServerList::getOnline();
610 servers = ServerList::getLocal();
613 int fav_idx = luaL_checkinteger(L,1) -1;
615 if ((fav_idx >= 0) &&
616 (fav_idx < (int) servers.size())) {
618 ServerList::deleteEntry(servers[fav_idx]);
624 /******************************************************************************/
625 int ModApiMainMenu::l_show_keys_menu(lua_State *L)
627 GUIEngine* engine = getGuiEngine(L);
628 sanity_check(engine != NULL);
630 GUIKeyChangeMenu *kmenu
631 = new GUIKeyChangeMenu( engine->m_device->getGUIEnvironment(),
634 engine->m_menumanager);
639 /******************************************************************************/
640 int ModApiMainMenu::l_create_world(lua_State *L)
642 const char *name = luaL_checkstring(L, 1);
643 int gameidx = luaL_checkinteger(L,2) -1;
645 std::string path = porting::path_user + DIR_DELIM
649 std::vector<SubgameSpec> games = getAvailableGames();
651 if ((gameidx >= 0) &&
652 (gameidx < (int) games.size())) {
654 // Create world if it doesn't exist
655 if (!loadGameConfAndInitWorld(path, games[gameidx])) {
656 lua_pushstring(L, "Failed to initialize world");
661 lua_pushstring(L, "Invalid game index");
666 /******************************************************************************/
667 int ModApiMainMenu::l_delete_world(lua_State *L)
669 int worldidx = luaL_checkinteger(L,1) -1;
671 std::vector<WorldSpec> worlds = getAvailableWorlds();
673 if ((worldidx >= 0) &&
674 (worldidx < (int) worlds.size())) {
676 WorldSpec spec = worlds[worldidx];
678 std::vector<std::string> paths;
679 paths.push_back(spec.path);
680 fs::GetRecursiveSubPaths(spec.path, paths);
683 if (!fs::DeletePaths(paths)) {
684 lua_pushstring(L, "Failed to delete world");
691 lua_pushstring(L, "Invalid world index");
696 /******************************************************************************/
697 int ModApiMainMenu::l_set_topleft_text(lua_State *L)
699 GUIEngine* engine = getGuiEngine(L);
700 sanity_check(engine != NULL);
702 std::string text = "";
704 if (!lua_isnone(L,1) && !lua_isnil(L,1))
705 text = luaL_checkstring(L, 1);
707 engine->setTopleftText(text);
711 /******************************************************************************/
712 int ModApiMainMenu::l_get_mapgen_names(lua_State *L)
714 std::vector<const char *> names;
715 Mapgen::getMapgenNames(&names, lua_toboolean(L, 1));
718 for (size_t i = 0; i != names.size(); i++) {
719 lua_pushstring(L, names[i]);
720 lua_rawseti(L, -2, i + 1);
727 /******************************************************************************/
728 int ModApiMainMenu::l_get_modpath(lua_State *L)
730 std::string modpath = fs::RemoveRelativePathComponents(
731 porting::path_user + DIR_DELIM + "mods" + DIR_DELIM);
732 lua_pushstring(L, modpath.c_str());
736 /******************************************************************************/
737 int ModApiMainMenu::l_get_gamepath(lua_State *L)
739 std::string gamepath = fs::RemoveRelativePathComponents(
740 porting::path_user + DIR_DELIM + "games" + DIR_DELIM);
741 lua_pushstring(L, gamepath.c_str());
745 /******************************************************************************/
746 int ModApiMainMenu::l_get_texturepath(lua_State *L)
748 std::string gamepath = fs::RemoveRelativePathComponents(
749 porting::path_user + DIR_DELIM + "textures");
750 lua_pushstring(L, gamepath.c_str());
754 int ModApiMainMenu::l_get_texturepath_share(lua_State *L)
756 std::string gamepath = fs::RemoveRelativePathComponents(
757 porting::path_share + DIR_DELIM + "textures");
758 lua_pushstring(L, gamepath.c_str());
762 /******************************************************************************/
763 int ModApiMainMenu::l_create_dir(lua_State *L) {
764 const char *path = luaL_checkstring(L, 1);
766 if (ModApiMainMenu::isMinetestPath(path)) {
767 lua_pushboolean(L, fs::CreateAllDirs(path));
771 lua_pushboolean(L, false);
775 /******************************************************************************/
776 int ModApiMainMenu::l_delete_dir(lua_State *L)
778 const char *path = luaL_checkstring(L, 1);
780 std::string absolute_path = fs::RemoveRelativePathComponents(path);
782 if (ModApiMainMenu::isMinetestPath(absolute_path)) {
783 lua_pushboolean(L, fs::RecursiveDelete(absolute_path));
787 lua_pushboolean(L, false);
791 /******************************************************************************/
792 int ModApiMainMenu::l_copy_dir(lua_State *L)
794 const char *source = luaL_checkstring(L, 1);
795 const char *destination = luaL_checkstring(L, 2);
797 bool keep_source = true;
799 if ((!lua_isnone(L,3)) &&
801 keep_source = lua_toboolean(L,3);
804 std::string absolute_destination = fs::RemoveRelativePathComponents(destination);
805 std::string absolute_source = fs::RemoveRelativePathComponents(source);
807 if ((ModApiMainMenu::isMinetestPath(absolute_source)) &&
808 (ModApiMainMenu::isMinetestPath(absolute_destination))) {
809 bool retval = fs::CopyDir(absolute_source,absolute_destination);
811 if (retval && (!keep_source)) {
813 retval &= fs::RecursiveDelete(absolute_source);
815 lua_pushboolean(L,retval);
818 lua_pushboolean(L,false);
822 /******************************************************************************/
823 int ModApiMainMenu::l_extract_zip(lua_State *L)
825 GUIEngine* engine = getGuiEngine(L);
826 sanity_check(engine);
828 const char *zipfile = luaL_checkstring(L, 1);
829 const char *destination = luaL_checkstring(L, 2);
831 std::string absolute_destination = fs::RemoveRelativePathComponents(destination);
833 if (ModApiMainMenu::isMinetestPath(absolute_destination)) {
834 fs::CreateAllDirs(absolute_destination);
836 io::IFileSystem* fs = engine->m_device->getFileSystem();
838 if (!fs->addFileArchive(zipfile,true,false,io::EFAT_ZIP)) {
839 lua_pushboolean(L,false);
843 sanity_check(fs->getFileArchiveCount() > 0);
845 /**********************************************************************/
846 /* WARNING this is not threadsafe!! */
847 /**********************************************************************/
848 io::IFileArchive* opened_zip =
849 fs->getFileArchive(fs->getFileArchiveCount()-1);
851 const io::IFileList* files_in_zip = opened_zip->getFileList();
853 unsigned int number_of_files = files_in_zip->getFileCount();
855 for (unsigned int i=0; i < number_of_files; i++) {
856 std::string fullpath = destination;
857 fullpath += DIR_DELIM;
858 fullpath += files_in_zip->getFullFileName(i).c_str();
859 std::string fullpath_dir = fs::RemoveLastPathComponent(fullpath);
861 if (!files_in_zip->isDirectory(i)) {
862 if (!fs::PathExists(fullpath_dir) && !fs::CreateAllDirs(fullpath_dir)) {
863 fs->removeFileArchive(fs->getFileArchiveCount()-1);
864 lua_pushboolean(L,false);
868 io::IReadFile* toread = opened_zip->createAndOpenFile(i);
870 FILE *targetfile = fopen(fullpath.c_str(),"wb");
872 if (targetfile == NULL) {
873 fs->removeFileArchive(fs->getFileArchiveCount()-1);
874 lua_pushboolean(L,false);
878 char read_buffer[1024];
881 while (total_read < toread->getSize()) {
883 unsigned int bytes_read =
884 toread->read(read_buffer,sizeof(read_buffer));
885 if ((bytes_read == 0 ) ||
886 (fwrite(read_buffer, 1, bytes_read, targetfile) != bytes_read))
889 fs->removeFileArchive(fs->getFileArchiveCount()-1);
890 lua_pushboolean(L,false);
893 total_read += bytes_read;
901 fs->removeFileArchive(fs->getFileArchiveCount()-1);
902 lua_pushboolean(L,true);
906 lua_pushboolean(L,false);
910 /******************************************************************************/
911 int ModApiMainMenu::l_get_mainmenu_path(lua_State *L)
913 GUIEngine* engine = getGuiEngine(L);
914 sanity_check(engine != NULL);
916 lua_pushstring(L,engine->getScriptDir().c_str());
920 /******************************************************************************/
921 bool ModApiMainMenu::isMinetestPath(std::string path)
923 if (fs::PathStartsWith(path,fs::TempPath()))
927 if (fs::PathStartsWith(path,fs::RemoveRelativePathComponents(porting::path_share + DIR_DELIM + "games")))
931 if (fs::PathStartsWith(path,fs::RemoveRelativePathComponents(porting::path_user + DIR_DELIM + "mods")))
935 if (fs::PathStartsWith(path,fs::RemoveRelativePathComponents(porting::path_user + DIR_DELIM + "worlds")))
942 /******************************************************************************/
943 int ModApiMainMenu::l_show_file_open_dialog(lua_State *L)
945 GUIEngine* engine = getGuiEngine(L);
946 sanity_check(engine != NULL);
948 const char *formname= luaL_checkstring(L, 1);
949 const char *title = luaL_checkstring(L, 2);
951 GUIFileSelectMenu* fileOpenMenu =
952 new GUIFileSelectMenu(engine->m_device->getGUIEnvironment(),
955 engine->m_menumanager,
958 fileOpenMenu->setTextDest(engine->m_buttonhandler);
959 fileOpenMenu->drop();
963 /******************************************************************************/
964 int ModApiMainMenu::l_download_file(lua_State *L)
966 const char *url = luaL_checkstring(L, 1);
967 const char *target = luaL_checkstring(L, 2);
970 std::string absolute_destination = fs::RemoveRelativePathComponents(target);
972 if (ModApiMainMenu::isMinetestPath(absolute_destination)) {
973 if (GUIEngine::downloadFile(url,absolute_destination)) {
974 lua_pushboolean(L,true);
978 errorstream << "DOWNLOAD denied: " << absolute_destination
979 << " isn't a allowed path" << std::endl;
981 lua_pushboolean(L,false);
985 /******************************************************************************/
986 int ModApiMainMenu::l_get_video_drivers(lua_State *L)
988 std::vector<irr::video::E_DRIVER_TYPE> drivers
989 = porting::getSupportedVideoDrivers();
992 for (u32 i = 0; i != drivers.size(); i++) {
993 const char *name = porting::getVideoDriverName(drivers[i]);
994 const char *fname = porting::getVideoDriverFriendlyName(drivers[i]);
997 lua_pushstring(L, name);
998 lua_setfield(L, -2, "name");
999 lua_pushstring(L, fname);
1000 lua_setfield(L, -2, "friendly_name");
1002 lua_rawseti(L, -2, i + 1);
1008 /******************************************************************************/
1009 int ModApiMainMenu::l_get_video_modes(lua_State *L)
1011 std::vector<core::vector3d<u32> > videomodes
1012 = porting::getSupportedVideoModes();
1015 for (u32 i = 0; i != videomodes.size(); i++) {
1017 lua_pushnumber(L, videomodes[i].X);
1018 lua_setfield(L, -2, "w");
1019 lua_pushnumber(L, videomodes[i].Y);
1020 lua_setfield(L, -2, "h");
1021 lua_pushnumber(L, videomodes[i].Z);
1022 lua_setfield(L, -2, "depth");
1024 lua_rawseti(L, -2, i + 1);
1030 /******************************************************************************/
1031 int ModApiMainMenu::l_gettext(lua_State *L)
1033 std::string text = strgettext(std::string(luaL_checkstring(L, 1)));
1034 lua_pushstring(L, text.c_str());
1039 /******************************************************************************/
1040 int ModApiMainMenu::l_get_screen_info(lua_State *L)
1043 int top = lua_gettop(L);
1044 lua_pushstring(L,"density");
1045 lua_pushnumber(L,porting::getDisplayDensity());
1046 lua_settable(L, top);
1048 lua_pushstring(L,"display_width");
1049 lua_pushnumber(L,porting::getDisplaySize().X);
1050 lua_settable(L, top);
1052 lua_pushstring(L,"display_height");
1053 lua_pushnumber(L,porting::getDisplaySize().Y);
1054 lua_settable(L, top);
1056 lua_pushstring(L,"window_width");
1057 lua_pushnumber(L,porting::getWindowSize().X);
1058 lua_settable(L, top);
1060 lua_pushstring(L,"window_height");
1061 lua_pushnumber(L,porting::getWindowSize().Y);
1062 lua_settable(L, top);
1066 /******************************************************************************/
1067 int ModApiMainMenu::l_get_min_supp_proto(lua_State *L)
1069 u16 proto_version_min = g_settings->getFlag("send_pre_v25_init") ?
1070 CLIENT_PROTOCOL_VERSION_MIN_LEGACY : CLIENT_PROTOCOL_VERSION_MIN;
1071 lua_pushinteger(L, proto_version_min);
1075 int ModApiMainMenu::l_get_max_supp_proto(lua_State *L)
1077 lua_pushinteger(L, CLIENT_PROTOCOL_VERSION_MAX);
1081 /******************************************************************************/
1082 int ModApiMainMenu::l_do_async_callback(lua_State *L)
1084 GUIEngine* engine = getGuiEngine(L);
1086 size_t func_length, param_length;
1087 const char* serialized_func_raw = luaL_checklstring(L, 1, &func_length);
1089 const char* serialized_param_raw = luaL_checklstring(L, 2, ¶m_length);
1091 sanity_check(serialized_func_raw != NULL);
1092 sanity_check(serialized_param_raw != NULL);
1094 std::string serialized_func = std::string(serialized_func_raw, func_length);
1095 std::string serialized_param = std::string(serialized_param_raw, param_length);
1097 lua_pushinteger(L, engine->queueAsync(serialized_func, serialized_param));
1102 /******************************************************************************/
1103 void ModApiMainMenu::Initialize(lua_State *L, int top)
1105 API_FCT(update_formspec);
1106 API_FCT(set_clouds);
1107 API_FCT(get_textlist_index);
1108 API_FCT(get_table_index);
1109 API_FCT(get_worlds);
1113 API_FCT(get_favorites);
1114 API_FCT(show_keys_menu);
1115 API_FCT(create_world);
1116 API_FCT(delete_world);
1117 API_FCT(delete_favorite);
1118 API_FCT(set_background);
1119 API_FCT(set_topleft_text);
1120 API_FCT(get_mapgen_names);
1121 API_FCT(get_modpath);
1122 API_FCT(get_gamepath);
1123 API_FCT(get_texturepath);
1124 API_FCT(get_texturepath_share);
1125 API_FCT(create_dir);
1126 API_FCT(delete_dir);
1128 API_FCT(extract_zip);
1129 API_FCT(get_mainmenu_path);
1130 API_FCT(show_file_open_dialog);
1131 API_FCT(download_file);
1132 API_FCT(get_modstore_details);
1133 API_FCT(get_modstore_list);
1135 API_FCT(get_video_drivers);
1136 API_FCT(get_video_modes);
1137 API_FCT(get_screen_info);
1138 API_FCT(get_min_supp_proto);
1139 API_FCT(get_max_supp_proto);
1140 API_FCT(do_async_callback);
1143 /******************************************************************************/
1144 void ModApiMainMenu::InitializeAsync(AsyncEngine& engine)
1147 ASYNC_API_FCT(get_worlds);
1148 ASYNC_API_FCT(get_games);
1149 ASYNC_API_FCT(get_favorites);
1150 ASYNC_API_FCT(get_mapgen_names);
1151 ASYNC_API_FCT(get_modpath);
1152 ASYNC_API_FCT(get_gamepath);
1153 ASYNC_API_FCT(get_texturepath);
1154 ASYNC_API_FCT(get_texturepath_share);
1155 ASYNC_API_FCT(create_dir);
1156 ASYNC_API_FCT(delete_dir);
1157 ASYNC_API_FCT(copy_dir);
1158 //ASYNC_API_FCT(extract_zip); //TODO remove dependency to GuiEngine
1159 ASYNC_API_FCT(download_file);
1160 ASYNC_API_FCT(get_modstore_details);
1161 ASYNC_API_FCT(get_modstore_list);
1162 //ASYNC_API_FCT(gettext); (gettext lib isn't threadsafe)