Infinite packet flood test for debugging the new network layer
[oweals/minetest.git] / src / main.cpp
index d93cdba1edf2f31b907a346fa04c8fb27cdf33f7..b959d8c6433eb47cace7361eab82dab9ee67d4c2 100644 (file)
@@ -411,10 +411,13 @@ Doing currently:
        //#pragma comment(linker, "/subsystem:windows /ENTRY:mainCRTStartup")
 #endif
 
+#include "irrlicht.h" // createDevice
+
+#include "main.h"
+#include "mainmenumanager.h"
 #include <iostream>
 #include <fstream>
 #include <locale.h>
-#include "main.h"
 #include "common_irrlicht.h"
 #include "debug.h"
 #include "test.h"
@@ -431,8 +434,11 @@ Doing currently:
 #include "game.h"
 #include "keycode.h"
 #include "tile.h"
-
+#include "defaultsettings.h"
 #include "gettext.h"
+#include "settings.h"
+#include "profiler.h"
+#include "log.h"
 
 // This makes textures
 ITextureSource *g_texturesource = NULL;
@@ -441,25 +447,23 @@ ITextureSource *g_texturesource = NULL;
        Settings.
        These are loaded from the config file.
 */
-
-Settings g_settings;
-// This is located in defaultsettings.cpp
-extern void set_default_settings();
+Settings main_settings;
+Settings *g_settings = &main_settings;
 
 // Global profiler
-Profiler g_profiler;
+Profiler main_profiler;
+Profiler *g_profiler = &main_profiler;
 
 /*
        Random stuff
 */
 
 /*
-       GUI Stuff
+       mainmenumanager.h
 */
 
 gui::IGUIEnvironment* guienv = NULL;
 gui::IGUIStaticText *guiroot = NULL;
-
 MainMenuManager g_menumgr;
 
 bool noMenuActive()
@@ -468,7 +472,6 @@ bool noMenuActive()
 }
 
 // Passed to menus to allow disconnecting and exiting
-
 MainGameCallback *g_gamecallback = NULL;
 
 /*
@@ -477,19 +480,17 @@ MainGameCallback *g_gamecallback = NULL;
 
 // Connection
 std::ostream *dout_con_ptr = &dummyout;
-std::ostream *derr_con_ptr = &dstream_no_stderr;
-//std::ostream *dout_con_ptr = &dstream_no_stderr;
-//std::ostream *derr_con_ptr = &dstream_no_stderr;
-//std::ostream *dout_con_ptr = &dstream;
-//std::ostream *derr_con_ptr = &dstream;
+std::ostream *derr_con_ptr = &verbosestream;
+//std::ostream *dout_con_ptr = &infostream;
+//std::ostream *derr_con_ptr = &errorstream;
 
 // Server
-std::ostream *dout_server_ptr = &dstream;
-std::ostream *derr_server_ptr = &dstream;
+std::ostream *dout_server_ptr = &infostream;
+std::ostream *derr_server_ptr = &errorstream;
 
 // Client
-std::ostream *dout_client_ptr = &dstream;
-std::ostream *derr_client_ptr = &dstream;
+std::ostream *dout_client_ptr = &infostream;
+std::ostream *derr_client_ptr = &errorstream;
 
 /*
        gettime.h implementation
@@ -563,10 +564,12 @@ public:
                // Remember whether each key is down or up
                if(event.EventType == irr::EET_KEY_INPUT_EVENT)
                {
-                       keyIsDown[event.KeyInput.Key] = event.KeyInput.PressedDown;
-
-                       if(event.KeyInput.PressedDown)
-                               keyWasDown[event.KeyInput.Key] = true;
+                       if(event.KeyInput.PressedDown) {
+                               keyIsDown.set(event.KeyInput);
+                               keyWasDown.set(event.KeyInput);
+                       } else {
+                               keyIsDown.unset(event.KeyInput);
+                       }
                }
 
                if(event.EventType == irr::EET_MOUSE_INPUT_EVENT)
@@ -579,7 +582,6 @@ public:
                        }
                        else
                        {
-                               //dstream<<"MyEventReceiver: mouse input"<<std::endl;
                                left_active = event.MouseInput.isLeftPressed();
                                middle_active = event.MouseInput.isMiddlePressed();
                                right_active = event.MouseInput.isRightPressed();
@@ -610,16 +612,17 @@ public:
                return false;
        }
 
-       bool IsKeyDown(EKEY_CODE keyCode) const
+       bool IsKeyDown(const KeyPress &keyCode) const
        {
                return keyIsDown[keyCode];
        }
        
        // Checks whether a key was down and resets the state
-       bool WasKeyDown(EKEY_CODE keyCode)
+       bool WasKeyDown(const KeyPress &keyCode)
        {
                bool b = keyWasDown[keyCode];
-               keyWasDown[keyCode] = false;
+               if (b)
+                       keyWasDown.unset(keyCode);
                return b;
        }
 
@@ -632,12 +635,9 @@ public:
 
        void clearInput()
        {
-               for(u32 i=0; i<KEY_KEY_CODES_COUNT; i++)
-               {
-                       keyIsDown[i] = false;
-                       keyWasDown[i] = false;
-               }
-               
+               keyIsDown.clear();
+               keyWasDown.clear();
+
                leftclicked = false;
                rightclicked = false;
                leftreleased = false;
@@ -670,9 +670,9 @@ private:
        IrrlichtDevice *m_device;
        
        // The current state of keys
-       bool keyIsDown[KEY_KEY_CODES_COUNT];
+       KeyList keyIsDown;
        // Whether a key has been pressed or not
-       bool keyWasDown[KEY_KEY_CODES_COUNT];
+       KeyList keyWasDown;
 };
 
 /*
@@ -687,11 +687,11 @@ public:
                m_receiver(receiver)
        {
        }
-       virtual bool isKeyDown(EKEY_CODE keyCode)
+       virtual bool isKeyDown(const KeyPress &keyCode)
        {
                return m_receiver->IsKeyDown(keyCode);
        }
-       virtual bool wasKeyDown(EKEY_CODE keyCode)
+       virtual bool wasKeyDown(const KeyPress &keyCode)
        {
                return m_receiver->WasKeyDown(keyCode);
        }
@@ -772,14 +772,13 @@ public:
                rightclicked = false;
                leftreleased = false;
                rightreleased = false;
-               for(u32 i=0; i<KEY_KEY_CODES_COUNT; ++i)
-                       keydown[i] = false;
+               keydown.clear();
        }
-       virtual bool isKeyDown(EKEY_CODE keyCode)
+       virtual bool isKeyDown(const KeyPress &keyCode)
        {
                return keydown[keyCode];
        }
-       virtual bool wasKeyDown(EKEY_CODE keyCode)
+       virtual bool wasKeyDown(const KeyPress &keyCode)
        {
                return false;
        }
@@ -848,8 +847,7 @@ public:
                        if(counter1 < 0.0)
                        {
                                counter1 = 0.1*Rand(1, 40);
-                               keydown[getKeySetting("keymap_jump")] =
-                                               !keydown[getKeySetting("keymap_jump")];
+                               keydown.toggle(getKeySetting("keymap_jump"));
                        }
                }
                {
@@ -858,8 +856,7 @@ public:
                        if(counter1 < 0.0)
                        {
                                counter1 = 0.1*Rand(1, 40);
-                               keydown[getKeySetting("keymap_special1")] =
-                                               !keydown[getKeySetting("keymap_special1")];
+                               keydown.toggle(getKeySetting("keymap_special1"));
                        }
                }
                {
@@ -868,8 +865,7 @@ public:
                        if(counter1 < 0.0)
                        {
                                counter1 = 0.1*Rand(1, 40);
-                               keydown[getKeySetting("keymap_forward")] =
-                                               !keydown[getKeySetting("keymap_forward")];
+                               keydown.toggle(getKeySetting("keymap_forward"));
                        }
                }
                {
@@ -878,8 +874,7 @@ public:
                        if(counter1 < 0.0)
                        {
                                counter1 = 0.1*Rand(1, 40);
-                               keydown[getKeySetting("keymap_left")] =
-                                               !keydown[getKeySetting("keymap_left")];
+                               keydown.toggle(getKeySetting("keymap_left"));
                        }
                }
                {
@@ -925,7 +920,7 @@ public:
                return (myrand()%(max-min+1))+min;
        }
 private:
-       bool keydown[KEY_KEY_CODES_COUNT];
+       KeyList keydown;
        v2s32 mousepos;
        v2s32 mousespeed;
        bool leftdown;
@@ -1029,7 +1024,7 @@ void SpeedTests()
 
                u32 dtime = timer.stop();
                u32 per_ms = n / dtime;
-               std::cout<<"Done. "<<dtime<<"ms, "
+               dstream<<"Done. "<<dtime<<"ms, "
                                <<per_ms<<"/ms"<<std::endl;
        }
 }
@@ -1081,12 +1076,37 @@ void drawMenuBackground(video::IVideoDriver* driver)
        }
 }
 
+class StderrLogOutput: public ILogOutput
+{
+public:
+       /* line: Full line with timestamp, level and thread */
+       void printLog(const std::string &line)
+       {
+               std::cerr<<line<<std::endl;
+       }
+} main_stderr_log_out;
+
+class DstreamNoStderrLogOutput: public ILogOutput
+{
+public:
+       /* line: Full line with timestamp, level and thread */
+       void printLog(const std::string &line)
+       {
+               dstream_no_stderr<<line<<std::endl;
+       }
+} main_dstream_no_stderr_log_out;
+
 int main(int argc, char *argv[])
 {
        /*
                Initialization
        */
 
+       log_add_output_maxlev(&main_stderr_log_out, LMT_ACTION);
+       log_add_output_all_levs(&main_dstream_no_stderr_log_out);
+
+       log_register_thread("main");
+
        // Set locale. This is for forcing '.' as the decimal point.
        std::locale::global(std::locale("C"));
        // This enables printing all characters in bitmap font
@@ -1113,6 +1133,7 @@ int main(int argc, char *argv[])
        allowed_options.insert("dstream-on-stderr", ValueSpec(VALUETYPE_FLAG));
 #endif
        allowed_options.insert("speedtests", ValueSpec(VALUETYPE_FLAG));
+       allowed_options.insert("info-on-stderr", ValueSpec(VALUETYPE_FLAG));
 
        Settings cmd_args;
        
@@ -1154,6 +1175,9 @@ int main(int argc, char *argv[])
        if(cmd_args.getFlag("dstream-on-stderr") == false)
                disable_stderr = true;
 #endif
+       
+       if(cmd_args.getFlag("info-on-stderr"))
+               log_add_output(&main_stderr_log_out, LMT_INFO);
 
        porting::signal_handler_init();
        bool &kill = *porting::signal_handler_killstatus();
@@ -1164,13 +1188,13 @@ int main(int argc, char *argv[])
        // Create user data directory
        fs::CreateDir(porting::path_userdata);
 
-       init_gettext((porting::path_data+"/../locale").c_str());
+       init_gettext((porting::path_data+DIR_DELIM+".."+DIR_DELIM+"locale").c_str());
        
        // Initialize debug streams
 #ifdef RUN_IN_PLACE
        std::string debugfile = DEBUGFILE;
 #else
-       std::string debugfile = porting::path_userdata+"/"+DEBUGFILE;
+       std::string debugfile = porting::path_userdata+DIR_DELIM+DEBUGFILE;
 #endif
        debugstreams_init(disable_stderr, debugfile.c_str());
        // Initialize debug stacks
@@ -1185,7 +1209,7 @@ int main(int argc, char *argv[])
        BEGIN_DEBUG_EXCEPTION_HANDLER
 
        // Print startup message
-       dstream<<DTIME<<PROJECT_NAME
+       actionstream<<PROJECT_NAME<<
                        " with SER_FMT_VER_HIGHEST="<<(int)SER_FMT_VER_HIGHEST
                        <<", "<<BUILD_INFO
                        <<std::endl;
@@ -1195,7 +1219,7 @@ int main(int argc, char *argv[])
        */
 
        // Initialize default settings
-       set_default_settings();
+       set_default_settings(g_settings);
        
        // Initialize sockets
        sockets_init();
@@ -1210,10 +1234,10 @@ int main(int argc, char *argv[])
        
        if(cmd_args.exists("config"))
        {
-               bool r = g_settings.readConfigFile(cmd_args.get("config").c_str());
+               bool r = g_settings->readConfigFile(cmd_args.get("config").c_str());
                if(r == false)
                {
-                       dstream<<"Could not read configuration from \""
+                       errorstream<<"Could not read configuration from \""
                                        <<cmd_args.get("config")<<"\""<<std::endl;
                        return 1;
                }
@@ -1222,14 +1246,16 @@ int main(int argc, char *argv[])
        else
        {
                core::array<std::string> filenames;
-               filenames.push_back(porting::path_userdata + "/minetest.conf");
+               filenames.push_back(porting::path_userdata +
+                               DIR_DELIM + "minetest.conf");
 #ifdef RUN_IN_PLACE
-               filenames.push_back(porting::path_userdata + "/../minetest.conf");
+               filenames.push_back(porting::path_userdata +
+                               DIR_DELIM + ".." + DIR_DELIM + "minetest.conf");
 #endif
 
                for(u32 i=0; i<filenames.size(); i++)
                {
-                       bool r = g_settings.readConfigFile(filenames[i].c_str());
+                       bool r = g_settings->readConfigFile(filenames[i].c_str());
                        if(r)
                        {
                                configpath = filenames[i];
@@ -1254,6 +1280,9 @@ int main(int argc, char *argv[])
        
        // Initial call with g_texturesource not set.
        init_mapnode();
+       // Must be called before g_texturesource is created
+       // (for texture atlas making)
+       init_mineral();
 
        /*
                Run unit tests
@@ -1280,17 +1309,17 @@ int main(int argc, char *argv[])
        u16 port = 30000;
        if(cmd_args.exists("port"))
                port = cmd_args.getU16("port");
-       else if(g_settings.exists("port"))
-               port = g_settings.getU16("port");
+       else if(g_settings->exists("port"))
+               port = g_settings->getU16("port");
        if(port == 0)
                port = 30000;
        
        // Map directory
-       std::string map_dir = porting::path_userdata+"/world";
+       std::string map_dir = porting::path_userdata+DIR_DELIM+"world";
        if(cmd_args.exists("map-dir"))
                map_dir = cmd_args.get("map-dir");
-       else if(g_settings.exists("map-dir"))
-               map_dir = g_settings.get("map-dir");
+       else if(g_settings->exists("map-dir"))
+               map_dir = g_settings->get("map-dir");
        
        // Run dedicated server if asked to
        if(cmd_args.getFlag("server"))
@@ -1324,10 +1353,10 @@ int main(int argc, char *argv[])
        }
        else
        {
-               address = g_settings.get("address");
+               address = g_settings->get("address");
        }
        
-       std::string playername = g_settings.get("name");
+       std::string playername = g_settings->get("name");
 
        /*
                Device initialization
@@ -1336,14 +1365,14 @@ int main(int argc, char *argv[])
        // Resolution selection
        
        bool fullscreen = false;
-       u16 screenW = g_settings.getU16("screenW");
-       u16 screenH = g_settings.getU16("screenH");
+       u16 screenW = g_settings->getU16("screenW");
+       u16 screenH = g_settings->getU16("screenH");
 
        // Determine driver
 
        video::E_DRIVER_TYPE driverType;
        
-       std::string driverstring = g_settings.get("video_driver");
+       std::string driverstring = g_settings->get("video_driver");
 
        if(driverstring == "null")
                driverType = video::EDT_NULL;
@@ -1359,7 +1388,7 @@ int main(int argc, char *argv[])
                driverType = video::EDT_OPENGL;
        else
        {
-               dstream<<"WARNING: Invalid video_driver specified; defaulting "
+               errorstream<<"WARNING: Invalid video_driver specified; defaulting "
                                "to opengl"<<std::endl;
                driverType = video::EDT_OPENGL;
        }
@@ -1378,6 +1407,21 @@ int main(int argc, char *argv[])
        if (device == 0)
                return 1; // could not create selected driver.
        
+       /*
+               Continue initialization
+       */
+
+       video::IVideoDriver* driver = device->getVideoDriver();
+
+       // Disable mipmaps (because some of them look ugly)
+       driver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, false);
+
+       /*
+               This changes the minimum allowed number of vertices in a VBO.
+               Default is 500.
+       */
+       //driver->setMinHardwareBufferVertexCount(50);
+
        // Set the window caption
        device->setWindowCaption(L"Minetest [Main Menu]");
        
@@ -1402,7 +1446,7 @@ int main(int argc, char *argv[])
        
        device->setResizable(true);
 
-       bool random_input = g_settings.getBool("random_input")
+       bool random_input = g_settings->getBool("random_input")
                        || cmd_args.getFlag("random-input");
        InputHandler *input = NULL;
        if(random_input)
@@ -1410,18 +1454,6 @@ int main(int argc, char *argv[])
        else
                input = new RealInputHandler(device, &receiver);
        
-       /*
-               Continue initialization
-       */
-
-       //video::IVideoDriver* driver = device->getVideoDriver();
-
-       /*
-               This changes the minimum allowed number of vertices in a VBO.
-               Default is 500.
-       */
-       //driver->setMinHardwareBufferVertexCount(50);
-
        scene::ISceneManager* smgr = device->getSceneManager();
 
        guienv = device->getGUIEnvironment();
@@ -1430,14 +1462,14 @@ int main(int argc, char *argv[])
        if(font)
                skin->setFont(font);
        else
-               dstream<<"WARNING: Font file was not found."
+               errorstream<<"WARNING: Font file was not found."
                                " Using default font."<<std::endl;
        // If font was not found, this will get us one
        font = skin->getFont();
        assert(font);
        
        u32 text_height = font->getDimension(L"Hello, world!").Height;
-       dstream<<"text_height="<<text_height<<std::endl;
+       infostream<<"text_height="<<text_height<<std::endl;
 
        //skin->setColor(gui::EGDC_BUTTON_TEXT, video::SColor(255,0,0,0));
        skin->setColor(gui::EGDC_BUTTON_TEXT, video::SColor(255,255,255,255));
@@ -1451,7 +1483,6 @@ int main(int argc, char *argv[])
        */
 
        init_mapnode(); // Second call with g_texturesource set
-       init_mineral();
 
        /*
                GUI stuff
@@ -1513,10 +1544,12 @@ int main(int argc, char *argv[])
                                menudata.address = narrow_to_wide(address);
                                menudata.name = narrow_to_wide(playername);
                                menudata.port = narrow_to_wide(itos(port));
-                               menudata.fancy_trees = g_settings.getBool("new_style_leaves");
-                               menudata.smooth_lighting = g_settings.getBool("smooth_lighting");
-                               menudata.creative_mode = g_settings.getBool("creative_mode");
-                               menudata.enable_damage = g_settings.getBool("enable_damage");
+                               menudata.fancy_trees = g_settings->getBool("new_style_leaves");
+                               menudata.smooth_lighting = g_settings->getBool("smooth_lighting");
+                               menudata.clouds_3d = g_settings->getBool("enable_3d_clouds");
+                               menudata.opaque_water = g_settings->getBool("opaque_water");
+                               menudata.creative_mode = g_settings->getBool("creative_mode");
+                               menudata.enable_damage = g_settings->getBool("enable_damage");
 
                                GUIMainMenu *menu =
                                                new GUIMainMenu(guienv, guiroot, -1, 
@@ -1525,7 +1558,7 @@ int main(int argc, char *argv[])
 
                                if(error_message != L"")
                                {
-                                       dstream<<"WARNING: error_message = "
+                                       errorstream<<"error_message = "
                                                        <<wide_to_narrow(error_message)<<std::endl;
 
                                        GUIMessageMenu *menu2 =
@@ -1537,7 +1570,7 @@ int main(int argc, char *argv[])
 
                                video::IVideoDriver* driver = device->getVideoDriver();
                                
-                               dstream<<"Created main menu"<<std::endl;
+                               infostream<<"Created main menu"<<std::endl;
 
                                while(device->run() && kill == false)
                                {
@@ -1562,7 +1595,7 @@ int main(int argc, char *argv[])
                                if(device->run() == false || kill == true)
                                        break;
                                
-                               dstream<<"Dropping main menu"<<std::endl;
+                               infostream<<"Dropping main menu"<<std::endl;
 
                                menu->drop();
                                
@@ -1579,16 +1612,18 @@ int main(int argc, char *argv[])
 
                                password = translatePassword(playername, menudata.password);
 
-                               //dstream<<"Main: password hash: '"<<password<<"'"<<std::endl;
+                               //infostream<<"Main: password hash: '"<<password<<"'"<<std::endl;
 
                                address = wide_to_narrow(menudata.address);
                                int newport = stoi(wide_to_narrow(menudata.port));
                                if(newport != 0)
                                        port = newport;
-                               g_settings.set("new_style_leaves", itos(menudata.fancy_trees));
-                               g_settings.set("smooth_lighting", itos(menudata.smooth_lighting));
-                               g_settings.set("creative_mode", itos(menudata.creative_mode));
-                               g_settings.set("enable_damage", itos(menudata.enable_damage));
+                               g_settings->set("new_style_leaves", itos(menudata.fancy_trees));
+                               g_settings->set("smooth_lighting", itos(menudata.smooth_lighting));
+                               g_settings->set("enable_3d_clouds", itos(menudata.clouds_3d));
+                               g_settings->set("opaque_water", itos(menudata.opaque_water));
+                               g_settings->set("creative_mode", itos(menudata.creative_mode));
+                               g_settings->set("enable_damage", itos(menudata.enable_damage));
                                
                                // NOTE: These are now checked server side; no need to do it
                                //       here, so let's not do it here.
@@ -1607,12 +1642,12 @@ int main(int argc, char *argv[])
                                }*/
 
                                // Save settings
-                               g_settings.set("name", playername);
-                               g_settings.set("address", address);
-                               g_settings.set("port", itos(port));
+                               g_settings->set("name", playername);
+                               g_settings->set("address", address);
+                               g_settings->set("port", itos(port));
                                // Update configuration file
                                if(configpath != "")
-                                       g_settings.updateConfigFile(configpath.c_str());
+                                       g_settings->updateConfigFile(configpath.c_str());
                        
                                // Continue to game
                                break;
@@ -1646,12 +1681,12 @@ int main(int argc, char *argv[])
                } //try
                catch(con::PeerNotFoundException &e)
                {
-                       dstream<<DTIME<<"Connection error (timed out?)"<<std::endl;
+                       errorstream<<"Connection error (timed out?)"<<std::endl;
                        error_message = L"Connection error (timed out?)";
                }
                catch(SocketException &e)
                {
-                       dstream<<DTIME<<"Socket error (port already in use?)"<<std::endl;
+                       errorstream<<"Socket error (port already in use?)"<<std::endl;
                        error_message = L"Socket error (port already in use?)";
                }
 #ifdef NDEBUG
@@ -1660,7 +1695,7 @@ int main(int argc, char *argv[])
                        std::string narrow_message = "Some exception, what()=\"";
                        narrow_message += e.what();
                        narrow_message += "\"";
-                       dstream<<DTIME<<narrow_message<<std::endl;
+                       errorstream<<narrow_message<<std::endl;
                        error_message = narrow_to_wide(narrow_message);
                }
 #endif
@@ -1674,7 +1709,7 @@ int main(int argc, char *argv[])
        */
        device->drop();
        
-       END_DEBUG_EXCEPTION_HANDLER
+       END_DEBUG_EXCEPTION_HANDLER(errorstream)
        
        debugstreams_deinit();