reorganized a lot of stuff and modified mapgen and objects slightly while doing it
[oweals/minetest.git] / src / servermain.cpp
index 5edc8ac7c0794c16c1efea2161936572649448bc..146c548c506d4a16c9e40f2cc3cff7fb152274aa 100644 (file)
@@ -20,18 +20,18 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 /*
 =============================== NOTES ==============================
 
-TODO: Move the default settings into some separate file
 
 */
 
 #ifndef SERVER
        #ifdef _WIN32
+               #pragma error ("For a server build, SERVER must be defined globally")
        #else
                #error "For a server build, SERVER must be defined globally"
        #endif
 #endif
 
-#ifdef UNITTEST_DISABLE
+#ifdef NDEBUG
        #ifdef _WIN32
                #pragma message ("Disabling unit tests")
        #else
@@ -49,15 +49,6 @@ TODO: Move the default settings into some separate file
 #pragma comment(lib, "zlibwapi.lib")
 #endif
 
-#ifdef _WIN32
-       #define WIN32_LEAN_AND_MEAN
-       #include <windows.h>
-       #define sleep_ms(x) Sleep(x)
-#else
-       #include <unistd.h>
-       #define sleep_ms(x) usleep(x*1000)
-#endif
-
 #include <iostream>
 #include <fstream>
 #include <time.h>
@@ -75,9 +66,10 @@ TODO: Move the default settings into some separate file
 #include "constants.h"
 #include "strfnd.h"
 #include "porting.h"
-
-// Dummy variable
-IrrlichtDevice *g_device = NULL;
+#include "materials.h"
+#include "config.h"
+#include "mineral.h"
+#include "filesys.h"
 
 /*
        Settings.
@@ -88,6 +80,12 @@ Settings g_settings;
 
 extern void set_default_settings();
 
+// Global profiler
+Profiler g_profiler;
+
+// A dummy thing
+ITextureSource *g_texturesource = NULL;
+
 /*
        Debug streams
 */
@@ -104,27 +102,29 @@ std::ostream *derr_server_ptr = &dstream;
 std::ostream *dout_client_ptr = &dstream;
 std::ostream *derr_client_ptr = &dstream;
 
-
 /*
-       Timestamp stuff
+       gettime.h implementation
 */
 
-JMutex g_timestamp_mutex;
-
-std::string getTimestamp()
+u32 getTimeMs()
 {
-       if(g_timestamp_mutex.IsInitialized()==false)
-               return "";
-       JMutexAutoLock lock(g_timestamp_mutex);
-       time_t t = time(NULL);
-       struct tm *tm = localtime(&t);
-       char cs[20];
-       strftime(cs, 20, "%H:%M:%S", tm);
-       return cs;
+       /*
+               Use imprecise system calls directly (from porting.h)
+       */
+       return porting::getTimeMs();
 }
 
 int main(int argc, char *argv[])
 {
+       /*
+               Initialization
+       */
+
+       // Set locale. This is for forcing '.' as the decimal point.
+       std::locale::global(std::locale("C"));
+       // This enables printing all characters in bitmap font
+       setlocale(LC_CTYPE, "en_US");
+
        /*
                Low-level initialization
        */
@@ -134,13 +134,39 @@ int main(int argc, char *argv[])
        disable_stderr = true;
 #endif
 
+       porting::signal_handler_init();
+       bool &kill = *porting::signal_handler_killstatus();
+       
+       // Initialize porting::path_data and porting::path_userdata
+       porting::initializePaths();
+
+       // Create user data directory
+       fs::CreateDir(porting::path_userdata);
+       
        // Initialize debug streams
-       debugstreams_init(disable_stderr, DEBUGFILE);
+#ifdef RUN_IN_PLACE
+       std::string debugfile = DEBUGFILE;
+#else
+       std::string debugfile = porting::path_userdata+"/"+DEBUGFILE;
+#endif
+       debugstreams_init(disable_stderr, debugfile.c_str());
        // Initialize debug stacks
        debug_stacks_init();
 
        DSTACK(__FUNCTION_NAME);
 
+       // Init material properties table
+       //initializeMaterialProperties();
+
+       // Debug handler
+       BEGIN_DEBUG_EXCEPTION_HANDLER
+
+       // Print startup message
+       dstream<<DTIME<<"minetest-c55"
+                       " with SER_FMT_VER_HIGHEST="<<(int)SER_FMT_VER_HIGHEST
+                       <<", "<<BUILD_INFO
+                       <<std::endl;
+       
        try
        {
        
@@ -156,6 +182,7 @@ int main(int argc, char *argv[])
        allowed_options.insert("port", ValueSpec(VALUETYPE_STRING));
        allowed_options.insert("disable-unittests", ValueSpec(VALUETYPE_FLAG));
        allowed_options.insert("enable-unittests", ValueSpec(VALUETYPE_FLAG));
+       allowed_options.insert("map-dir", ValueSpec(VALUETYPE_STRING));
 
        Settings cmd_args;
        
@@ -196,28 +223,10 @@ int main(int argc, char *argv[])
        // Initialize default settings
        set_default_settings();
        
-       // Print startup message
-       dstream<<DTIME<<"minetest-c55 server"
-                       " with SER_FMT_VER_HIGHEST="<<(int)SER_FMT_VER_HIGHEST
-                       <<", ENABLE_TESTS="<<ENABLE_TESTS
-                       <<std::endl;
-       
-       // Set locale. This is for forcing '.' as the decimal point.
-       std::locale::global(std::locale("C"));
-       // This enables printing all characters in bitmap font
-       setlocale(LC_CTYPE, "en_US");
-
        // Initialize sockets
        sockets_init();
        atexit(sockets_cleanup);
        
-       // Initialize timestamp mutex
-       g_timestamp_mutex.Init();
-
-       /*
-               Initialization
-       */
-
        /*
                Read config file
        */
@@ -238,15 +247,15 @@ int main(int argc, char *argv[])
        }
        else
        {
-               const char *filenames[2] =
-               {
-                       "../minetest.conf",
-                       "../../minetest.conf"
-               };
+               core::array<std::string> filenames;
+               filenames.push_back(porting::path_userdata + "/minetest.conf");
+#ifdef RUN_IN_PLACE
+               filenames.push_back(porting::path_userdata + "/../minetest.conf");
+#endif
 
-               for(u32 i=0; i<2; i++)
+               for(u32 i=0; i<filenames.size(); i++)
                {
-                       bool r = g_settings.readConfigFile(filenames[i]);
+                       bool r = g_settings.readConfigFile(filenames[i].c_str());
                        if(r)
                        {
                                configpath = filenames[i];
@@ -257,6 +266,12 @@ int main(int argc, char *argv[])
 
        // Initialize random seed
        srand(time(0));
+       mysrand(time(0));
+
+       // Initialize stuff
+       
+       init_mapnode();
+       init_mineral();
 
        /*
                Run unit tests
@@ -266,18 +281,6 @@ int main(int argc, char *argv[])
        {
                run_tests();
        }
-       
-       // Read map parameters from settings
-
-       HMParams hm_params;
-       hm_params.blocksize = g_settings.getU16("heightmap_blocksize");
-       hm_params.randmax = g_settings.get("height_randmax");
-       hm_params.randfactor = g_settings.get("height_randfactor");
-       hm_params.base = g_settings.get("height_base");
-
-       MapParams map_params;
-       map_params.plants_amount = g_settings.getFloat("plants_amount");
-       map_params.ravines_amount = g_settings.getFloat("ravines_amount");
 
        /*
                Check parameters
@@ -292,19 +295,17 @@ int main(int argc, char *argv[])
        <<"|  Y Y  \\  |   |  \\  ___/|  | \\  ___/ \\___ \\  |  |  "<<std::endl
        <<"|__|_|  /__|___|  /\\___  >__|  \\___  >____  > |__|  "<<std::endl
        <<"      \\/        \\/     \\/          \\/     \\/        "<<std::endl
-       <<std::endl
-       <<"Now with more waterish water!"
        <<std::endl;
 
        std::cout<<std::endl;
        
        // Port?
        u16 port = 30000;
-       if(cmd_args.exists("port"))
+       if(cmd_args.exists("port") && cmd_args.getU16("port") != 0)
        {
                port = cmd_args.getU16("port");
        }
-       else if(g_settings.exists("port"))
+       else if(g_settings.exists("port") && g_settings.getU16("port") != 0)
        {
                port = g_settings.getU16("port");
        }
@@ -314,70 +315,27 @@ int main(int argc, char *argv[])
                                <<std::endl;
        }
        
-       DSTACK("Dedicated server branch");
+       // Figure out path to map
+       std::string map_dir = porting::path_userdata+"/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");
        
-       std::cout<<std::endl;
-       std::cout<<"========================"<<std::endl;
-       std::cout<<"Running dedicated server"<<std::endl;
-       std::cout<<"========================"<<std::endl;
-       std::cout<<std::endl;
-
-       Server server("../map", hm_params, map_params);
+       // Create server
+       Server server(map_dir.c_str());
        server.start(port);
 
-       for(;;)
-       {
-               // This is kind of a hack but can be done like this
-               // because server.step() is very light
-               sleep_ms(30);
-               server.step(0.030);
-
-               static int counter = 0;
-               counter--;
-               if(counter <= 0)
-               {
-                       counter = 10;
-
-                       core::list<PlayerInfo> list = server.getPlayerInfo();
-                       core::list<PlayerInfo>::Iterator i;
-                       static u32 sum_old = 0;
-                       u32 sum = PIChecksum(list);
-                       if(sum != sum_old)
-                       {
-                               std::cout<<DTIME<<"Player info:"<<std::endl;
-                               for(i=list.begin(); i!=list.end(); i++)
-                               {
-                                       i->PrintLine(&std::cout);
-                               }
-                       }
-                       sum_old = sum;
-               }
-       }
-
-       /*
-               Update configuration file
-       */
-       if(configpath != "")
-       {
-               g_settings.updateConfigFile(configpath.c_str());
-       }
-
+       // Run server
+       dedicated_server_loop(server, kill);
+       
        } //try
        catch(con::PeerNotFoundException &e)
        {
                dstream<<DTIME<<"Connection timed out."<<std::endl;
        }
-#if CATCH_UNHANDLED_EXCEPTIONS
-       /*
-               This is what has to be done in every thread to get suitable debug info
-       */
-       catch(std::exception &e)
-       {
-               dstream<<std::endl<<DTIME<<"An unhandled exception occurred: "
-                               <<e.what()<<std::endl;
-               assert(0);
-       }
-#endif
+
+       END_DEBUG_EXCEPTION_HANDLER
 
        debugstreams_deinit();