Add "simple singleplayer mode"; Fix a number of GUI things
authorPerttu Ahola <celeron55@gmail.com>
Thu, 15 Mar 2012 13:20:20 +0000 (15:20 +0200)
committerPerttu Ahola <celeron55@gmail.com>
Thu, 15 Mar 2012 13:20:20 +0000 (15:20 +0200)
src/game.cpp
src/game.h
src/guiMainMenu.cpp
src/guiMainMenu.h
src/guiPauseMenu.cpp
src/guiPauseMenu.h
src/main.cpp
src/server.cpp
src/server.h

index 465e83ea58fa59cf143474136bd66255234e1bfd..7d6f884e9ad8adf66a9ef1a3531edfa273dc1d31 100644 (file)
@@ -658,7 +658,8 @@ void the_game(
        std::wstring &error_message,
        std::string configpath,
        ChatBackend &chat_backend,
-       const SubgameSpec &gamespec // Used for local game
+       const SubgameSpec &gamespec, // Used for local game,
+       bool simple_singleplayer_mode
 )
 {
        video::IVideoDriver* driver = device->getVideoDriver();
@@ -709,7 +710,8 @@ void the_game(
        if(address == ""){
                draw_load_screen(L"Creating server...", driver, font);
                infostream<<"Creating server"<<std::endl;
-               server = new Server(map_dir, configpath, gamespec);
+               server = new Server(map_dir, configpath, gamespec,
+                               simple_singleplayer_mode);
                server->start(port);
        }
 
@@ -1357,7 +1359,7 @@ void the_game(
                                        <<"Launching pause menu"<<std::endl;
                        // It will delete itself by itself
                        (new GUIPauseMenu(guienv, guiroot, -1, g_gamecallback,
-                                       &g_menumgr))->drop();
+                                       &g_menumgr, simple_singleplayer_mode))->drop();
 
                        // Move mouse cursor on top of the disconnect button
                        input->setMousePos(displaycenter.X, displaycenter.Y+25);
index 4ca5a2433956ca1cfa69bd6ca653a6e5651b6602..596945e9905e93806910a81cf2e8a808fbdc9500 100644 (file)
@@ -138,7 +138,8 @@ void the_game(
        std::wstring &error_message,
        std::string configpath,
        ChatBackend &chat_backend,
-       const SubgameSpec &gamespec // Used for local game
+       const SubgameSpec &gamespec, // Used for local game
+       bool simple_singleplayer_mode
 );
 
 #endif
index 346471337f94508970660a907287e81284c7e012..40f51f97c4c7d95b8fff6b82c31511002ba6d2e5 100644 (file)
@@ -720,15 +720,13 @@ void GUIMainMenu::readInput(MainMenuData *dst)
                if(e != NULL && e->getType() == gui::EGUIET_TAB_CONTROL)
                        dst->selected_tab = ((gui::IGUITabControl*)e)->getActiveTab();
        }
-       if(getTab() == TAB_SINGLEPLAYER)
+       if(dst->selected_tab == TAB_SINGLEPLAYER)
        {
-               dst->name = L"singleplayer";
-               dst->password = L"";
-               dst->address = L"";
-               dst->port = 30000;
+               dst->simple_singleplayer_mode = true;
        }
        else
        {
+               dst->simple_singleplayer_mode = false;
                {
                        gui::IGUIElement *e = getElementFromId(GUI_ID_NAME_INPUT);
                        if(e != NULL)
index 5cb0f8e2bcf4dda11b439f669f09da5edf091721..5f9e73f62a113c5fe0a1c492fdcc8cdf871135d5 100644 (file)
@@ -45,6 +45,7 @@ struct MainMenuData
        bool creative_mode;
        bool enable_damage;
        int selected_world;
+       bool simple_singleplayer_mode;
        // Actions
        WorldSpec delete_world_spec;
        std::wstring create_world_name;
@@ -62,7 +63,8 @@ struct MainMenuData
                // Server opts
                creative_mode(false),
                enable_damage(false),
-               selected_world(0)
+               selected_world(0),
+               simple_singleplayer_mode(false)
        {}
 };
 
index 3b1861b3db92b1adfd788b74c2928f1d35372e98..e542a28e90ce63e1baed8637a483933715718b73 100644 (file)
@@ -34,10 +34,12 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 GUIPauseMenu::GUIPauseMenu(gui::IGUIEnvironment* env,\r
                gui::IGUIElement* parent, s32 id,\r
                IGameCallback *gamecallback,\r
-               IMenuManager *menumgr):\r
-       GUIModalMenu(env, parent, id, menumgr)\r
+               IMenuManager *menumgr,\r
+               bool simple_singleplayer_mode):\r
+       GUIModalMenu(env, parent, id, menumgr),\r
+       m_gamecallback(gamecallback),\r
+       m_simple_singleplayer_mode(simple_singleplayer_mode)\r
 {\r
-       m_gamecallback = gamecallback;\r
 }\r
 \r
 GUIPauseMenu::~GUIPauseMenu()\r
@@ -106,7 +108,7 @@ void GUIPauseMenu::regenerateGui(v2u32 screensize)
        */\r
        const s32 btn_height = 30;\r
        const s32 btn_gap = 20;\r
-       const s32 btn_num = 4;\r
+       const s32 btn_num = m_simple_singleplayer_mode ? 3 : 4;\r
        s32 btn_y = size.Y/2-((btn_num*btn_height+(btn_num-1)*btn_gap))/2;\r
        changeCtype("");\r
        {\r
@@ -116,18 +118,21 @@ void GUIPauseMenu::regenerateGui(v2u32 screensize)
                        wgettext("Continue"));\r
        }\r
        btn_y += btn_height + btn_gap;\r
+       if(!m_simple_singleplayer_mode)\r
        {\r
-               core::rect<s32> rect(0, 0, 140, btn_height);\r
-               rect = rect + v2s32(size.X/2-140/2, btn_y);\r
-               Environment->addButton(rect, this, 261,\r
-                       wgettext("Change Password"));\r
+               {\r
+                       core::rect<s32> rect(0, 0, 140, btn_height);\r
+                       rect = rect + v2s32(size.X/2-140/2, btn_y);\r
+                       Environment->addButton(rect, this, 261,\r
+                               wgettext("Change Password"));\r
+               }\r
+               btn_y += btn_height + btn_gap;\r
        }\r
-       btn_y += btn_height + btn_gap;\r
        {\r
                core::rect<s32> rect(0, 0, 140, btn_height);\r
                rect = rect + v2s32(size.X/2-140/2, btn_y);\r
                Environment->addButton(rect, this, 260,\r
-                       wgettext("Disconnect"));\r
+                       wgettext("Exit to Menu"));\r
        }\r
        btn_y += btn_height + btn_gap;\r
        {\r
index 64e3c71f1d45a349aae990b25d1ab6fde1390476..8514a6f0f8a7c9b6be6106e4bb9a5c693e4b3d34 100644 (file)
@@ -37,7 +37,8 @@ public:
        GUIPauseMenu(gui::IGUIEnvironment* env,\r
                        gui::IGUIElement* parent, s32 id,\r
                        IGameCallback *gamecallback,\r
-                       IMenuManager *menumgr);\r
+                       IMenuManager *menumgr,\r
+                       bool simple_singleplayer_mode);\r
        ~GUIPauseMenu();\r
        \r
        void removeChildren();\r
@@ -52,6 +53,7 @@ public:
        \r
 private:\r
        IGameCallback *m_gamecallback;\r
+       bool m_simple_singleplayer_mode;\r
 };\r
 \r
 #endif\r
index 2925f048c5ea9dbffa89dfaacccb6614460f3bff..3e4686134e58c0757eee130db49dd986d64e8570 100644 (file)
@@ -1063,7 +1063,7 @@ int main(int argc, char *argv[])
                infostream<<"Using gamespec \""<<gamespec.id<<"\""<<std::endl;
 
                // Create server
-               Server server(world_path, configpath, gamespec);
+               Server server(world_path, configpath, gamespec, false);
                server.start(port);
                
                // Run server
@@ -1253,6 +1253,13 @@ int main(int argc, char *argv[])
                        
                        SubgameSpec gamespec;
                        WorldSpec worldspec;
+                       bool simple_singleplayer_mode = false;
+
+                       // These are set up based on the menu and other things
+                       std::string current_playername = "invĀ£lid";
+                       std::string current_password = "";
+                       std::string current_address = "does-not-exist";
+                       int current_port = 0;
 
                        /*
                                Out-of-game menu loop.
@@ -1377,6 +1384,7 @@ int main(int argc, char *argv[])
                                int newport = stoi(wide_to_narrow(menudata.port));
                                if(newport != 0)
                                        port = newport;
+                               simple_singleplayer_mode = menudata.simple_singleplayer_mode;
                                // Save settings
                                g_settings->setS32("selected_mainmenu_tab", menudata.selected_tab);
                                g_settings->set("new_style_leaves", itos(menudata.fancy_trees));
@@ -1391,14 +1399,24 @@ int main(int argc, char *argv[])
                                if(menudata.selected_world != -1)
                                        g_settings->set("selected_world_path",
                                                        worldspecs[menudata.selected_world].path);
-                               /*// Update configuration file
-                               if(configpath != "")
-                                       g_settings->updateConfigFile(configpath.c_str());*/
                                
                                // Break out of menu-game loop to shut down cleanly
                                if(device->run() == false || kill == true)
                                        break;
                                
+                               current_playername = playername;
+                               current_password = password;
+                               current_address = address;
+                               current_port = port;
+
+                               // If using simple singleplayer mode, override
+                               if(simple_singleplayer_mode){
+                                       current_playername = "singleplayer";
+                                       current_password = "";
+                                       current_address = "";
+                                       current_port = 30011;
+                               }
+                               
                                // Set world path to selected one
                                if(menudata.selected_world != -1){
                                        worldspec = worldspecs[menudata.selected_world];
@@ -1435,7 +1453,7 @@ int main(int argc, char *argv[])
                                }
 
                                // If local game
-                               if(address == "")
+                               if(current_address == "")
                                {
                                        if(menudata.selected_world == -1){
                                                error_message = L"No world selected and no address "
@@ -1474,7 +1492,7 @@ int main(int argc, char *argv[])
                        // Break out of menu-game loop to shut down cleanly
                        if(device->run() == false || kill == true)
                                break;
-                       
+
                        /*
                                Run game
                        */
@@ -1485,14 +1503,15 @@ int main(int argc, char *argv[])
                                device,
                                font,
                                worldspec.path,
-                               playername,
-                               password,
-                               address,
-                               port,
+                               current_playername,
+                               current_password,
+                               current_address,
+                               current_port,
                                error_message,
                                configpath,
                                chat_backend,
-                               gamespec
+                               gamespec,
+                               simple_singleplayer_mode
                        );
 
                } //try
index cb4813ed8663c4232c4dd27d409b200c3ab86e9d..a74a2ee758ac1fbb3cce72533e7478204a169de0 100644 (file)
@@ -836,11 +836,13 @@ void PlayerInfo::PrintLine(std::ostream *s)
 Server::Server(
                const std::string &path_world,
                const std::string &path_config,
-               const SubgameSpec &gamespec
+               const SubgameSpec &gamespec,
+               bool simple_singleplayer_mode
        ):
        m_path_world(path_world),
        m_path_config(path_config),
        m_gamespec(gamespec),
+       m_simple_singleplayer_mode(simple_singleplayer_mode),
        m_async_fatal_error(""),
        m_env(NULL),
        m_con(PROTOCOL_ID, 512, CONNECTION_TIMEOUT, this),
@@ -880,7 +882,11 @@ Server::Server(
        // share/server
        m_path_share = porting::path_share + DIR_DELIM + "server";
 
-       infostream<<"Server created for gameid \""<<m_gamespec.id<<"\""<<std::endl;
+       infostream<<"Server created for gameid \""<<m_gamespec.id<<"\"";
+       if(m_simple_singleplayer_mode)
+               infostream<<" in simple singleplayer mode"<<std::endl;
+       else
+               infostream<<std::endl;
        infostream<<"- world:  "<<m_path_world<<std::endl;
        infostream<<"- config: "<<m_path_config<<std::endl;
        infostream<<"- game:   "<<m_gamespec.path<<std::endl;
@@ -2105,6 +2111,16 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
                        SendAccessDenied(m_con, peer_id, L"Invalid password");
                        return;
                }
+
+               // Do not allow multiple players in simple singleplayer mode.
+               // This isn't a perfect way to do it, but will suffice for now.
+               if(m_simple_singleplayer_mode && m_clients.size() > 1){
+                       infostream<<"Server: Not allowing another client to connect in"
+                                       <<" simple singleplayer mode"<<std::endl;
+                       SendAccessDenied(m_con, peer_id,
+                                       L"Running in simple singleplayer mode.");
+                       return;
+               }
                
                // Enforce user limit.
                // Don't enforce for users that have some admin right
@@ -2204,21 +2220,25 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
                        m_con.Send(peer_id, 0, data, true);
                }
                
-               // Send information about server to player in chat
-               SendChatMessage(peer_id, getStatusString());
-               
-               // Send information about joining in chat
+               // Note things in chat if not in simple singleplayer mode
+               if(!m_simple_singleplayer_mode)
                {
-                       std::wstring name = L"unknown";
-                       Player *player = m_env->getPlayer(peer_id);
-                       if(player != NULL)
-                               name = narrow_to_wide(player->getName());
+                       // Send information about server to player in chat
+                       SendChatMessage(peer_id, getStatusString());
                        
-                       std::wstring message;
-                       message += L"*** ";
-                       message += name;
-                       message += L" joined game";
-                       BroadcastChatMessage(message);
+                       // Send information about joining in chat
+                       {
+                               std::wstring name = L"unknown";
+                               Player *player = m_env->getPlayer(peer_id);
+                               if(player != NULL)
+                                       name = narrow_to_wide(player->getName());
+                               
+                               std::wstring message;
+                               message += L"*** ";
+                               message += name;
+                               message += L" joined game";
+                               BroadcastChatMessage(message);
+                       }
                }
                
                // Warnings about protocol version can be issued here
index 0b4c67deb10a0008cb3fb1a10ff8529760039232..31e3ed1767d4e7d91cde4fb6b56f28d03c04a5eb 100644 (file)
@@ -410,7 +410,8 @@ public:
        Server(
                const std::string &path_world,
                const std::string &path_config,
-               const SubgameSpec &gamespec
+               const SubgameSpec &gamespec,
+               bool simple_singleplayer_mode
        );
        ~Server();
        void start(unsigned short port);
@@ -659,6 +660,9 @@ private:
        std::string m_path_config;
        // Subgame specification
        SubgameSpec m_gamespec;
+       // If true, do not allow multiple players and hide some multiplayer
+       // functionality
+       bool m_simple_singleplayer_mode;
 
        // Equivalent of /usr/share/minetest/server
        std::string m_path_share;