World creation button and dialog and functionality
authorPerttu Ahola <celeron55@gmail.com>
Mon, 12 Mar 2012 22:06:37 +0000 (00:06 +0200)
committerPerttu Ahola <celeron55@gmail.com>
Mon, 12 Mar 2012 22:06:37 +0000 (00:06 +0200)
src/CMakeLists.txt
src/guiCreateWorld.cpp [new file with mode: 0644]
src/guiCreateWorld.h [new file with mode: 0644]
src/guiKeyChangeMenu.cpp
src/guiKeyChangeMenu.h
src/guiMainMenu.cpp
src/guiMainMenu.h
src/main.cpp
src/server.cpp
src/subgame.cpp
src/subgame.h

index cec42719a8e1f95e8c6cdfaec59b53b4c452b795..18184365f165f2c7e13c6c81cd29147caa5d23e0 100644 (file)
@@ -179,6 +179,7 @@ set(minetest_SRCS
        guiPasswordChange.cpp
        guiDeathScreen.cpp
        guiChatConsole.cpp
+       guiCreateWorld.cpp
        client.cpp
        tile.cpp
        game.cpp
diff --git a/src/guiCreateWorld.cpp b/src/guiCreateWorld.cpp
new file mode 100644 (file)
index 0000000..7143f95
--- /dev/null
@@ -0,0 +1,255 @@
+/*
+Minetest-c55
+Copyright (C) 2012 celeron55, Perttu Ahola <celeron55@gmail.com>
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#include "guiCreateWorld.h"
+#include "debug.h"
+#include "serialization.h"
+#include <string>
+#include <IGUICheckBox.h>
+#include <IGUIEditBox.h>
+#include <IGUIButton.h>
+#include <IGUIStaticText.h>
+#include <IGUIFont.h>
+#include <IGUIListBox.h>
+
+#include "gettext.h"
+
+enum
+{
+       GUI_ID_NAME_INPUT = 101,
+       GUI_ID_GAME_LISTBOX,
+       GUI_ID_CREATE,
+       GUI_ID_CANCEL
+};
+
+GUICreateWorld::GUICreateWorld(gui::IGUIEnvironment* env,
+               gui::IGUIElement* parent, s32 id,
+               IMenuManager *menumgr,
+               CreateWorldDest *dest,
+               const std::vector<SubgameSpec> &games
+):
+       GUIModalMenu(env, parent, id, menumgr),
+       m_dest(dest),
+       m_games(games)
+{
+       assert(games.size() > 0);
+}
+
+GUICreateWorld::~GUICreateWorld()
+{
+       removeChildren();
+       if(m_dest)
+               delete m_dest;
+}
+
+void GUICreateWorld::removeChildren()
+{
+       const core::list<gui::IGUIElement*> &children = getChildren();
+       core::list<gui::IGUIElement*> children_copy;
+       for(core::list<gui::IGUIElement*>::ConstIterator
+                       i = children.begin(); i != children.end(); i++)
+       {
+               children_copy.push_back(*i);
+       }
+       for(core::list<gui::IGUIElement*>::Iterator
+                       i = children_copy.begin();
+                       i != children_copy.end(); i++)
+       {
+               (*i)->remove();
+       }
+}
+
+void GUICreateWorld::regenerateGui(v2u32 screensize)
+{
+       std::wstring name = L"";
+
+       {
+               gui::IGUIElement *e = getElementFromId(GUI_ID_NAME_INPUT);
+               if(e != NULL)
+                       name = e->getText();
+       }
+
+       /*
+               Remove stuff
+       */
+       removeChildren();
+       
+       /*
+               Calculate new sizes and positions
+       */
+       core::rect<s32> rect(
+                       screensize.X/2 - 580/2,
+                       screensize.Y/2 - 300/2,
+                       screensize.X/2 + 580/2,
+                       screensize.Y/2 + 300/2
+       );
+       
+       DesiredRect = rect;
+       recalculateAbsolutePosition(false);
+
+       v2s32 size = rect.getSize();
+
+       v2s32 topleft = v2s32(10+80, 10+70);
+
+       /*
+               Add stuff
+       */
+       {
+               core::rect<s32> rect(0, 0, 100, 20);
+               rect += v2s32(0, 5) + topleft;
+               Environment->addStaticText(wgettext("World name"),
+                       rect, false, true, this, -1);
+       }
+       {
+               core::rect<s32> rect(0, 0, 300, 30);
+               rect = rect + v2s32(100, 0) + topleft;
+               gui::IGUIElement *e = 
+               Environment->addEditBox(name.c_str(), rect, true, this, GUI_ID_NAME_INPUT);
+               Environment->setFocus(e);
+
+               irr::SEvent evt;
+               evt.EventType = EET_KEY_INPUT_EVENT;
+               evt.KeyInput.Key = KEY_END;
+               evt.KeyInput.PressedDown = true;
+               e->OnEvent(evt);
+       }
+       {
+               core::rect<s32> rect(0, 0, 100, 20);
+               rect += v2s32(0, 40+5) + topleft;
+               Environment->addStaticText(wgettext("Game"),
+                       rect, false, true, this, -1);
+       }
+       {
+               core::rect<s32> rect(0, 0, 300, 80);
+               rect += v2s32(100, 40) + topleft;
+               gui::IGUIListBox *e = Environment->addListBox(rect, this,
+                               GUI_ID_GAME_LISTBOX);
+               e->setDrawBackground(true);
+               for(u32 i=0; i<m_games.size(); i++){
+                       std::wostringstream os(std::ios::binary);
+                       os<<narrow_to_wide(m_games[i].name).c_str();
+                       os<<L" [";
+                       os<<narrow_to_wide(m_games[i].id).c_str();
+                       os<<L"]";
+                       e->addItem(os.str().c_str());
+               }
+               e->setSelected(0);
+       }
+       changeCtype("");
+       {
+               core::rect<s32> rect(0, 0, 120, 30);
+               rect = rect + v2s32(170, 140) + topleft;
+               Environment->addButton(rect, this, GUI_ID_CANCEL,
+                       wgettext("Cancel"));
+       }
+       {
+               core::rect<s32> rect(0, 0, 120, 30);
+               rect = rect + v2s32(300, 140) + topleft;
+               Environment->addButton(rect, this, GUI_ID_CREATE,
+                       wgettext("Create"));
+       }
+       changeCtype("C");
+}
+
+void GUICreateWorld::drawMenu()
+{
+       gui::IGUISkin* skin = Environment->getSkin();
+       if (!skin)
+               return;
+       video::IVideoDriver* driver = Environment->getVideoDriver();
+       
+       video::SColor bgcolor(140,0,0,0);
+       driver->draw2DRectangle(bgcolor, AbsoluteRect, &AbsoluteClippingRect);
+
+       gui::IGUIElement::draw();
+}
+
+void GUICreateWorld::acceptInput()
+{
+       if(m_dest)
+       {
+               gui::IGUIElement *e = getElementFromId(GUI_ID_NAME_INPUT);
+               if(e != NULL)
+               {
+                       m_dest->accepted(e->getText(), m_games[0].id);
+               }
+               delete m_dest;
+               m_dest = NULL;
+       }
+}
+
+bool GUICreateWorld::OnEvent(const SEvent& event)
+{
+       if(event.EventType==EET_KEY_INPUT_EVENT)
+       {
+               if(event.KeyInput.Key==KEY_ESCAPE && event.KeyInput.PressedDown)
+               {
+                       quitMenu();
+                       return true;
+               }
+               if(event.KeyInput.Key==KEY_RETURN && event.KeyInput.PressedDown)
+               {
+                       acceptInput();
+                       quitMenu();
+                       return true;
+               }
+       }
+       if(event.EventType==EET_GUI_EVENT)
+       {
+               if(event.GUIEvent.EventType==gui::EGET_ELEMENT_FOCUS_LOST
+                               && isVisible())
+               {
+                       if(!canTakeFocus(event.GUIEvent.Element))
+                       {
+                               dstream<<"GUICreateWorld: Not allowing focus change."
+                                               <<std::endl;
+                               // Returning true disables focus change
+                               return true;
+                       }
+               }
+               bool accept_input = false;
+               if(event.GUIEvent.EventType==gui::EGET_BUTTON_CLICKED){
+                       switch(event.GUIEvent.Caller->getID()){
+                       case GUI_ID_CANCEL:
+                               quitMenu();
+                               return true;
+                               break;
+                       case GUI_ID_CREATE:
+                               accept_input = true;
+                               break;
+                       }
+               }
+               if(event.GUIEvent.EventType==gui::EGET_EDITBOX_ENTER){
+                       switch(event.GUIEvent.Caller->getID()){
+                       case GUI_ID_NAME_INPUT:
+                               accept_input = true;
+                               break;
+                       }
+               }
+               if(accept_input){
+                       acceptInput();
+                       quitMenu();
+                       // quitMenu deallocates menu
+                       return true;
+               }
+       }
+
+       return Parent ? Parent->OnEvent(event) : false;
+}
+
diff --git a/src/guiCreateWorld.h b/src/guiCreateWorld.h
new file mode 100644 (file)
index 0000000..525b449
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+Minetest-c55
+Copyright (C) 2012 celeron55, Perttu Ahola <celeron55@gmail.com>
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#ifndef GUICREATEWORLD_HEADER
+#define GUICREATEWORLD_HEADER
+
+#include "common_irrlicht.h"
+#include "modalMenu.h"
+#include "utility.h"
+#include <string>
+#include "subgame.h"
+
+struct CreateWorldDest
+{
+       virtual void accepted(std::wstring name, std::string gameid) = 0;
+       virtual ~CreateWorldDest() {};
+};
+
+class GUICreateWorld : public GUIModalMenu
+{
+public:
+       GUICreateWorld(gui::IGUIEnvironment* env,
+                       gui::IGUIElement* parent, s32 id,
+                       IMenuManager *menumgr,
+                       CreateWorldDest *dest,
+                       const std::vector<SubgameSpec> &games);
+       ~GUICreateWorld();
+       
+       void removeChildren();
+       /*
+               Remove and re-add (or reposition) stuff
+       */
+       void regenerateGui(v2u32 screensize);
+
+       void drawMenu();
+
+       void acceptInput();
+
+       bool OnEvent(const SEvent& event);
+       
+private:
+       CreateWorldDest *m_dest;
+       std::vector<SubgameSpec> m_games;
+};
+
+#endif
+
index 0c84f8ffa9cb2786ecd0004782b475a19d28f640..fb49ab65953d05e751a3fb342d848fe84487cba6 100644 (file)
 #include <IGUIFont.h>
 #include "settings.h"
 
+enum
+{
+       GUI_ID_BACK_BUTTON = 101, GUI_ID_ABORT_BUTTON, GUI_ID_SCROLL_BAR,
+       //buttons
+       GUI_ID_KEY_FORWARD_BUTTON,
+       GUI_ID_KEY_BACKWARD_BUTTON,
+       GUI_ID_KEY_LEFT_BUTTON,
+       GUI_ID_KEY_RIGHT_BUTTON,
+       GUI_ID_KEY_USE_BUTTON,
+       GUI_ID_KEY_FLY_BUTTON,
+       GUI_ID_KEY_FAST_BUTTON,
+       GUI_ID_KEY_JUMP_BUTTON,
+       GUI_ID_KEY_CHAT_BUTTON,
+       GUI_ID_KEY_CMD_BUTTON,
+       GUI_ID_KEY_CONSOLE_BUTTON,
+       GUI_ID_KEY_SNEAK_BUTTON,
+       GUI_ID_KEY_DROP_BUTTON,
+       GUI_ID_KEY_INVENTORY_BUTTON,
+       GUI_ID_KEY_DUMP_BUTTON,
+       GUI_ID_KEY_RANGE_BUTTON
+};
+
 GUIKeyChangeMenu::GUIKeyChangeMenu(gui::IGUIEnvironment* env,
                gui::IGUIElement* parent, s32 id, IMenuManager *menumgr) :
        GUIModalMenu(env, parent, id, menumgr)
index 9772bde3c8d2d88780e486a407a5db24d2d71567..1ff3d40451b4227754796ce77fb78d63ab51ff84 100644 (file)
 #include "keycode.h"
 #include <string>
 
-enum
-{
-       GUI_ID_BACK_BUTTON = 101, GUI_ID_ABORT_BUTTON, GUI_ID_SCROLL_BAR,
-       //buttons
-       GUI_ID_KEY_FORWARD_BUTTON,
-       GUI_ID_KEY_BACKWARD_BUTTON,
-       GUI_ID_KEY_LEFT_BUTTON,
-       GUI_ID_KEY_RIGHT_BUTTON,
-       GUI_ID_KEY_USE_BUTTON,
-       GUI_ID_KEY_FLY_BUTTON,
-       GUI_ID_KEY_FAST_BUTTON,
-       GUI_ID_KEY_JUMP_BUTTON,
-       GUI_ID_KEY_CHAT_BUTTON,
-       GUI_ID_KEY_CMD_BUTTON,
-       GUI_ID_KEY_CONSOLE_BUTTON,
-       GUI_ID_KEY_SNEAK_BUTTON,
-       GUI_ID_KEY_DROP_BUTTON,
-       GUI_ID_KEY_INVENTORY_BUTTON,
-       GUI_ID_KEY_DUMP_BUTTON,
-       GUI_ID_KEY_RANGE_BUTTON
-};
-
 class GUIKeyChangeMenu: public GUIModalMenu
 {
 public:
index 184984051018c4ecd19652609d4a502748007061..6d07fe9733c6e6df46556a4da1446d8a242066d6 100644 (file)
@@ -1,6 +1,6 @@
 /*
 Minetest-c55
-Copyright (C) 2010 celeron55, Perttu Ahola <celeron55@gmail.com>
+Copyright (C) 2010-12 celeron55, Perttu Ahola <celeron55@gmail.com>
 
 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
@@ -19,6 +19,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 
 #include "guiMainMenu.h"
 #include "guiKeyChangeMenu.h"
+#include "guiCreateWorld.h"
+#include "guiMessageMenu.h"
 #include "debug.h"
 #include "serialization.h"
 #include <string>
@@ -28,9 +30,41 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include <IGUIStaticText.h>
 #include <IGUIFont.h>
 #include <IGUIListBox.h>
+// For IGameCallback
+#include "guiPauseMenu.h"
+#include "gettext.h"
+#include "utility.h"
 
+struct CreateWorldDestMainMenu : public CreateWorldDest
+{
+       CreateWorldDestMainMenu(GUIMainMenu *menu):
+               m_menu(menu)
+       {}
+       void accepted(std::wstring name, std::string gameid)
+       {
+               m_menu->createNewWorld(name, gameid);
+       }
+       GUIMainMenu *m_menu;
+};
 
-#include "gettext.h"
+enum
+{
+       GUI_ID_QUIT_BUTTON = 101,
+       GUI_ID_NAME_INPUT,
+       GUI_ID_ADDRESS_INPUT,
+       GUI_ID_PORT_INPUT,
+       GUI_ID_FANCYTREE_CB,
+       GUI_ID_SMOOTH_LIGHTING_CB,
+       GUI_ID_3D_CLOUDS_CB,
+       GUI_ID_OPAQUE_WATER_CB,
+       GUI_ID_DAMAGE_CB,
+       GUI_ID_CREATIVE_CB,
+       GUI_ID_JOIN_GAME_BUTTON,
+       GUI_ID_CHANGE_KEYS_BUTTON,
+       GUI_ID_DELETE_WORLD_BUTTON,
+       GUI_ID_CREATE_WORLD_BUTTON,
+       GUI_ID_WORLD_LISTBOX,
+};
 
 GUIMainMenu::GUIMainMenu(gui::IGUIEnvironment* env,
                gui::IGUIElement* parent, s32 id,
@@ -264,6 +298,13 @@ void GUIMainMenu::regenerateGui(v2u32 screensize)
                Environment->addButton(rect, this, GUI_ID_DELETE_WORLD_BUTTON,
                          wgettext("Delete world"));
        }
+       // Create world button
+       {
+               core::rect<s32> rect(0, 0, 130, 30);
+               rect += topleft_server + v2s32(20+250+20+140, 90);
+               Environment->addButton(rect, this, GUI_ID_CREATE_WORLD_BUTTON,
+                         wgettext("Create world"));
+       }
        // World selection listbox
        {
                core::rect<s32> rect(0, 0, 250, 120);
@@ -407,7 +448,7 @@ bool GUIMainMenu::OnEvent(const SEvent& event)
                {
                        switch(event.GUIEvent.Caller->getID())
                        {
-                       case GUI_ID_JOIN_GAME_BUTTON: // Start game
+                       case GUI_ID_JOIN_GAME_BUTTON:
                                acceptInput();
                                quitMenu();
                                return true;
@@ -416,12 +457,28 @@ bool GUIMainMenu::OnEvent(const SEvent& event)
                                kmenu->drop();
                                return true;
                        }
-                       case GUI_ID_DELETE_WORLD_BUTTON: // Delete world
+                       case GUI_ID_DELETE_WORLD_BUTTON: {
                                acceptInput();
                                m_data->delete_world = true;
                                quitMenu();
                                return true;
                        }
+                       case GUI_ID_CREATE_WORLD_BUTTON: {
+                               std::vector<SubgameSpec> games = getAvailableGames();
+                               if(games.size() == 0){
+                                       GUIMessageMenu *menu = new GUIMessageMenu(env, parent,
+                                                       -1, menumgr,
+                                                       wgettext("Cannot create world: No games found"));
+                                       menu->drop();
+                               } else {
+                                       CreateWorldDest *dest = new CreateWorldDestMainMenu(this);
+                                       GUICreateWorld *menu = new GUICreateWorld(env, parent, -1,
+                                                       menumgr, dest, games);
+                                       menu->drop();
+                               }
+                               return true;
+                       }
+                       }
                }
                if(event.GUIEvent.EventType==gui::EGET_EDITBOX_ENTER)
                {
@@ -449,3 +506,13 @@ bool GUIMainMenu::OnEvent(const SEvent& event)
        return Parent ? Parent->OnEvent(event) : false;
 }
 
+void GUIMainMenu::createNewWorld(std::wstring name, std::string gameid)
+{
+       if(name == L"")
+               return;
+       acceptInput();
+       m_data->create_world_name = name;
+       m_data->create_world_gameid = gameid;
+       quitMenu();
+}
+
index 8ea33cf135758dc262cf0600db3aa0483cd21b18..08c585b88b038d870c2808888cf438b7794fd0b0 100644 (file)
@@ -1,6 +1,6 @@
 /*
 Minetest-c55
-Copyright (C) 2010 celeron55, Perttu Ahola <celeron55@gmail.com>
+Copyright (C) 2010-2012 celeron55, Perttu Ahola <celeron55@gmail.com>
 
 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
@@ -22,46 +22,14 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 
 #include "common_irrlicht.h"
 #include "modalMenu.h"
-#include "utility.h"
 #include <string>
-// For IGameCallback
-#include "guiPauseMenu.h"
 #include <list>
-
-enum
-{
-       GUI_ID_QUIT_BUTTON = 101,
-       GUI_ID_NAME_INPUT,
-       GUI_ID_ADDRESS_INPUT,
-       GUI_ID_PORT_INPUT,
-       GUI_ID_FANCYTREE_CB,
-       GUI_ID_SMOOTH_LIGHTING_CB,
-       GUI_ID_3D_CLOUDS_CB,
-       GUI_ID_OPAQUE_WATER_CB,
-       GUI_ID_DAMAGE_CB,
-       GUI_ID_CREATIVE_CB,
-       GUI_ID_JOIN_GAME_BUTTON,
-       GUI_ID_CHANGE_KEYS_BUTTON,
-       GUI_ID_DELETE_WORLD_BUTTON,
-       GUI_ID_WORLD_LISTBOX,
-};
+#include "subgame.h"
+class IGameCallback;
 
 struct MainMenuData
 {
-       MainMenuData():
-               // Client opts
-               fancy_trees(false),
-               smooth_lighting(false),
-               // Server opts
-               creative_mode(false),
-               enable_damage(false),
-               selected_world(0),
-               // Actions
-               delete_world(false)
-       {}
-
        // These are in the native format of the gui elements
-       
        // Client options
        std::wstring address;
        std::wstring port;
@@ -75,10 +43,25 @@ struct MainMenuData
        bool creative_mode;
        bool enable_damage;
        int selected_world;
-       // If map deletion is requested, this is set to true
+       // Actions
        bool delete_world;
+       std::wstring create_world_name;
+       std::string create_world_gameid;
 
        std::list<std::wstring> worlds;
+       std::vector<SubgameSpec> games;
+
+       MainMenuData():
+               // Client opts
+               fancy_trees(false),
+               smooth_lighting(false),
+               // Server opts
+               creative_mode(false),
+               enable_damage(false),
+               selected_world(0),
+               // Actions
+               delete_world(false)
+       {}
 };
 
 class GUIMainMenu : public GUIModalMenu
@@ -92,23 +75,15 @@ public:
        ~GUIMainMenu();
        
        void removeChildren();
-       /*
-               Remove and re-add (or reposition) stuff
-       */
+       // Remove and re-add (or reposition) stuff
        void regenerateGui(v2u32 screensize);
-
        void drawMenu();
-
        void readInput(MainMenuData *dst);
-
        void acceptInput();
-
        bool getStatus()
-       {
-               return m_accepted;
-       }
-
+       { return m_accepted; }
        bool OnEvent(const SEvent& event);
+       void createNewWorld(std::wstring name, std::string gameid);
        
 private:
        MainMenuData *m_data;
index 41cf583f5740c2bed78d1ca30dbb12040a3169a7..2f9c69fe1eaa02746831d7f67fe80bda4fb067a1 100644 (file)
@@ -1298,7 +1298,7 @@ int main(int argc, char *argv[])
                                        std::string gameid = getWorldGameId(commanded_world, true);
                                        if(gameid == "")
                                                gameid = g_settings->get("default_game");
-                                       WorldSpec spec(commanded_world, "[commanded world]", gameid);
+                                       WorldSpec spec(commanded_world, "--world", gameid);
                                        worldspecs.push_back(spec);
                                        menudata.worlds.push_back(narrow_to_wide(spec.name)
                                                        +L" ["+narrow_to_wide(spec.gameid)+L"]");
@@ -1363,7 +1363,7 @@ int main(int argc, char *argv[])
                                                        <<" ["<<worldspec.path<<"]"<<std::endl;
                                }
                                
-                               // Delete map if requested
+                               // Delete world if requested
                                if(menudata.delete_world)
                                {
                                        if(menudata.selected_world == -1){
@@ -1383,6 +1383,22 @@ int main(int argc, char *argv[])
                                        continue;
                                }
 
+                               // Create new world if requested
+                               if(menudata.create_world_name != L"")
+                               {
+                                       std::string path = porting::path_user + DIR_DELIM
+                                                       + "server" + DIR_DELIM + "worlds" + DIR_DELIM
+                                                       + wide_to_narrow(menudata.create_world_name);
+                                       // Create world if it doesn't exist
+                                       if(!initializeWorld(path, menudata.create_world_gameid)){
+                                               error_message = L"Failed to initialize world";
+                                               errorstream<<wide_to_narrow(error_message)<<std::endl;
+                                               continue;
+                                       }
+                                       g_settings->set("selected_world_path", path);
+                                       continue;
+                               }
+
                                playername = wide_to_narrow(menudata.name);
                                password = translatePassword(playername, menudata.password);
                                //infostream<<"Main: password hash: '"<<password<<"'"<<std::endl;
index 63bf794ab4ee191f15df762bcf380e470f556840..cb4813ed8663c4232c4dd27d409b200c3ab86e9d 100644 (file)
@@ -907,14 +907,9 @@ Server::Server(
                infostream<<"- mods:   "<<modspath<<std::endl;
        }
        
-       // Create world.mt if does not already exist
-       std::string worldmt_path = m_path_world + DIR_DELIM + "world.mt";
-       if(!fs::PathExists(worldmt_path)){
-               infostream<<"Creating world.mt ("<<worldmt_path<<")"<<std::endl;
-               fs::CreateAllDirs(m_path_world);
-               std::ofstream of(worldmt_path.c_str(), std::ios::binary);
-               of<<"gameid = "<<m_gamespec.id<<"\n";
-       }
+       // Create world if it doesn't exist
+       if(!initializeWorld(m_path_world, m_gamespec.id))
+               throw ServerError("Failed to initialize world");
 
        // Lock environment
        JMutexAutoLock envlock(m_env_mutex);
index 2fa3b7944137c3ba2229738f0a12ff35fb79cdcc..58881ecb8f982920befaf14e2bb45bb6058c5d76 100644 (file)
@@ -46,7 +46,9 @@ SubgameSpec findSubgame(const std::string &id)
                                + DIR_DELIM + id);
        addon_paths.insert(user_server + DIR_DELIM + "addons"
                        + DIR_DELIM + id);
-       return SubgameSpec(id, game_path, addon_paths);
+       // TODO: Read proper name from game_path/game.conf
+       std::string game_name = id;
+       return SubgameSpec(id, game_path, addon_paths, game_name);
 }
 
 std::set<std::string> getAvailableGameIds()
@@ -69,6 +71,16 @@ std::set<std::string> getAvailableGameIds()
        return gameids;
 }
 
+std::vector<SubgameSpec> getAvailableGames()
+{
+       std::vector<SubgameSpec> specs;
+       std::set<std::string> gameids = getAvailableGameIds();
+       for(std::set<std::string>::const_iterator i = gameids.begin();
+                       i != gameids.end(); i++)
+               specs.push_back(findSubgame(*i));
+       return specs;
+}
+
 #define LEGACY_GAMEID "mesetint"
 
 std::string getWorldGameId(const std::string &world_path, bool can_be_legacy)
@@ -132,4 +144,18 @@ std::vector<WorldSpec> getAvailableWorlds()
        return worlds;
 }
 
+bool initializeWorld(const std::string &path, const std::string &gameid)
+{
+       infostream<<"Initializing world at "<<path<<std::endl;
+       // Create world.mt if does not already exist
+       std::string worldmt_path = path + DIR_DELIM + "world.mt";
+       if(!fs::PathExists(worldmt_path)){
+               infostream<<"Creating world.mt ("<<worldmt_path<<")"<<std::endl;
+               fs::CreateAllDirs(path);
+               std::ofstream of(worldmt_path.c_str(), std::ios::binary);
+               of<<"gameid = "<<gameid<<"\n";
+       }
+       return true;
+}
+
 
index 1daeb8b151e881a0687db9ebb253bc23e4327e2d..b201a740255acdaa735d0eecbea725fb1fc9cd4e 100644 (file)
@@ -29,13 +29,16 @@ struct SubgameSpec
        std::string id; // "" = game does not exist
        std::string path;
        std::set<std::string> addon_paths;
+       std::string name;
 
        SubgameSpec(const std::string &id_="",
                        const std::string &path_="",
-                       const std::set<std::string> &addon_paths_=std::set<std::string>()):
+                       const std::set<std::string> &addon_paths_=std::set<std::string>(),
+                       const std::string &name_=""):
                id(id_),
                path(path_),
-               addon_paths(addon_paths_)
+               addon_paths(addon_paths_),
+               name(name_)
        {}
 
        bool isValid() const
@@ -47,6 +50,7 @@ struct SubgameSpec
 SubgameSpec findSubgame(const std::string &id);
 
 std::set<std::string> getAvailableGameIds();
+std::vector<SubgameSpec> getAvailableGames();
 
 std::string getWorldGameId(const std::string &world_path,
                bool can_be_legacy=false);
@@ -75,5 +79,8 @@ struct WorldSpec
 
 std::vector<WorldSpec> getAvailableWorlds();
 
+// Create world directory and world.mt if they don't exist
+bool initializeWorld(const std::string &path, const std::string &gameid);
+
 #endif