Ctrl+C handling on POSIX, some commands for server and other tweaking
authorPerttu Ahola <celeron55@gmail.com>
Tue, 15 Feb 2011 14:11:24 +0000 (16:11 +0200)
committerPerttu Ahola <celeron55@gmail.com>
Tue, 15 Feb 2011 14:11:24 +0000 (16:11 +0200)
13 files changed:
doc/changelog.txt
minetest.conf.example
src/CMakeLists.txt
src/guiPauseMenu.cpp
src/main.cpp
src/mapblock.cpp
src/porting.cpp
src/porting.h
src/server.cpp
src/server.h
src/servermain.cpp
src/test.cpp
src/utility.h

index 424f98bcfd01a63c500b1f9f4df06746ea40fe8e..a8722f1c9bb2c16a2cde7758ec43fec6a69bb819 100644 (file)
@@ -1,5 +1,7 @@
 Minetest-c55 changelog
 ----------------------
+This should contain all the major changes.
+For minor stuff, refer to the commit log of the repository.
 
 2011-02-14:
 - Created changelog.txt
index 264d77e5a36d10db198db42e7daa23a253442344..37c93a5a2479a1a26bd9163479cf873bd73f32d6 100644 (file)
@@ -31,6 +31,8 @@
 
 #map-dir = /home/palle/custom_map
 
+#operator_name = 
+
 #plants_amount = 1.0
 #ravines_amount = 1.0
 #coal_amount = 1.0
index 7fefc0238d91b298dc11396a58fcaecbff671e4d..6d9601c6548f7916a1654c9224aca80e634e6999 100644 (file)
@@ -5,6 +5,8 @@ if(RUN_IN_PLACE)
        add_definitions ( -DRUN_IN_PLACE )
 endif(RUN_IN_PLACE)
 
+set(USE_GPROF 0 CACHE BOOL "Use -pg flag for g++")
+
 # Use cmake_config.h
 add_definitions ( -DUSE_CMAKE_CONFIG_H )
 
@@ -161,6 +163,10 @@ else()
 
        set(CMAKE_CXX_FLAGS_RELEASE "-DNDEBUG ${WARNING_FLAGS} -O3 -ffast-math -Wall -fomit-frame-pointer -pipe -funroll-loops")
        set(CMAKE_CXX_FLAGS_DEBUG "-g -O1 -Wall")
+
+       if(USE_GPROF)
+               set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -pg")
+       endif()
        
        if(BUILD_SERVER)
                set_target_properties(minetestserver PROPERTIES
index b6f913d6be6a2a432b8fb899b81d2c8dde24bedf..2d42fdb77dec4189933ed5de7f3fd7f1a2043277 100644 (file)
@@ -174,10 +174,18 @@ bool GUIPauseMenu::OnEvent(const SEvent& event)
 {\r
        if(event.EventType==EET_KEY_INPUT_EVENT)\r
        {\r
-               if(event.KeyInput.Key==KEY_ESCAPE && event.KeyInput.PressedDown)\r
+               if(event.KeyInput.PressedDown)\r
                {\r
-                       quitMenu();\r
-                       return true;\r
+                       if(event.KeyInput.Key==KEY_ESCAPE)\r
+                       {\r
+                               quitMenu();\r
+                               return true;\r
+                       }\r
+                       else if(event.KeyInput.Key==KEY_RETURN)\r
+                       {\r
+                               quitMenu();\r
+                               return true;\r
+                       }\r
                }\r
        }\r
        if(event.EventType==EET_GUI_EVENT)\r
index bcc8dc446c256d6ef3a9fef8d3f353c0fd546ee7..452030a24454501c55f067c1e5676d540420f081 100644 (file)
@@ -268,7 +268,7 @@ Doing now (most important at the top):
 # maybe done\r
 * not done\r
 \r
-=== Stuff to do before release\r
+=== Fixmes\r
 * Make server find the spawning place from the real map data, not from\r
   the heightmap\r
   - But the changing borders of chunk have to be avoided, because\r
@@ -277,15 +277,15 @@ Doing now (most important at the top):
   placement and transfer\r
 * only_from_disk might not work anymore - check and fix it.\r
 * Check the fixmes in the list above\r
-* FIXME: Sneaking doesn't switch sneak node when moving sideways\r
+* When sending blocks to the client, the server takes way too much\r
+  CPU time (20-30% for single player), find out what it is doing.\r
+  - Make a simple profiler\r
 \r
 === Making it more portable\r
 * Some MSVC: std::sto* are defined without a namespace and collide\r
   with the ones in utility.h\r
-* On Kray's machine, the new find_library(XXF86VM_LIBRARY, Xxf86vm)\r
-  line doesn't find the library.\r
 \r
-=== Stuff to do after release\r
+=== Features\r
 * Make an "environment metafile" to store at least time of day\r
 * Move digging property stuff from material.{h,cpp} to mapnode.cpp...\r
   - Or maybe move content_features to material.{h,cpp}?\r
@@ -567,7 +567,25 @@ struct TextDestChat : public TextDest
        }\r
        void gotText(std::wstring text)\r
        {\r
+               // Discard empty line\r
+               if(text == L"")\r
+                       return;\r
+               \r
+               // Parse command (server command starts with "/#")\r
+               if(text[0] == L'/' && text[1] != L'#')\r
+               {\r
+                       std::wstring reply = L"Local: ";\r
+\r
+                       reply += L"Local commands not yet supported. "\r
+                                       "Server prefix is \"/#\".";\r
+                       \r
+                       m_client->addChatMessage(reply);\r
+                       return;\r
+               }\r
+\r
+               // Send to others\r
                m_client->sendChatMessage(text);\r
+               // Show locally\r
                m_client->addChatMessage(text);\r
        }\r
 \r
@@ -1546,6 +1564,9 @@ int main(int argc, char *argv[])
 \r
        DSTACK(__FUNCTION_NAME);\r
 \r
+       porting::signal_handler_init();\r
+       bool &kill = *porting::signal_handler_killstatus();\r
+       \r
        porting::initializePaths();\r
        // Create user data directory\r
        fs::CreateDir(porting::path_userdata);\r
@@ -1681,7 +1702,7 @@ int main(int argc, char *argv[])
                server.start(port);\r
                \r
                // Run server\r
-               dedicated_server_loop(server);\r
+               dedicated_server_loop(server, kill);\r
 \r
                return 0;\r
        }\r
index 422d3b531296e2b4ac6aca0e2ba472f9927a6862..1dbbe5c4ef43122b35a54e6abac7071e32c78005 100644 (file)
@@ -1771,11 +1771,11 @@ void MapBlock::serialize(std::ostream &os, u8 version)
                // First byte
                u8 flags = 0;
                if(is_underground)
-                       flags |= 1;
+                       flags |= 0x01;
                if(m_day_night_differs)
-                       flags |= 2;
+                       flags |= 0x02;
                if(m_lighting_expired)
-                       flags |= 3;
+                       flags |= 0x04;
                os.write((char*)&flags, 1);
 
                u32 nodecount = MAP_BLOCKSIZE*MAP_BLOCKSIZE*MAP_BLOCKSIZE;
@@ -1895,9 +1895,9 @@ void MapBlock::deSerialize(std::istream &is, u8 version)
 
                u8 flags;
                is.read((char*)&flags, 1);
-               is_underground = (flags & 1) ? true : false;
-               m_day_night_differs = (flags & 2) ? true : false;
-               m_lighting_expired = (flags & 3) ? true : false;
+               is_underground = (flags & 0x01) ? true : false;
+               m_day_night_differs = (flags & 0x02) ? true : false;
+               m_lighting_expired = (flags & 0x04) ? true : false;
 
                // Uncompress data
                std::ostringstream os(std::ios_base::binary);
index 592636336f14ef215e5636dc5a5b8bf54bb28ea4..f92b291acd5059ca35c6fc257746afb5e7760a0b 100644 (file)
@@ -29,6 +29,53 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 namespace porting
 {
 
+/*
+       Signal handler (grabs Ctrl-C on POSIX systems)
+*/
+
+#if !defined(_WIN32) // POSIX
+       #include <signal.h>
+
+bool g_killed = false;
+
+void sigint_handler(int sig)
+{
+       if(g_killed == false)
+       {
+               dstream<<DTIME<<"sigint_handler(): "
+                               <<"Ctrl-C pressed, shutting down."<<std::endl;
+               g_killed = true;
+       }
+       else
+       {
+               (void)signal(SIGINT, SIG_DFL);
+       }
+}
+
+void signal_handler_init(void)
+{
+       dstream<<"signal_handler_init()"<<std::endl;
+       (void)signal(SIGINT, sigint_handler);
+}
+
+#else // _WIN32
+
+void signal_handler_init(void)
+{
+       // No-op
+}
+
+#endif
+
+bool * signal_handler_killstatus(void)
+{
+       return &g_killed;
+}
+
+/*
+       Path mangler
+*/
+
 std::string path_data = "../data";
 std::string path_userdata = "../";
 
index 3133fcc804e275b6fb81b21e88b72b092dc18932..3cf8df594b82d66f5710c6c24c50317d29cf914d 100644 (file)
@@ -25,7 +25,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #define PORTING_HEADER
 
 #include <string>
-// Included for u64 and such
+// Included for u32 and such
 #include "common_irrlicht.h"
 #include "debug.h"
 #include "constants.h"
@@ -47,6 +47,15 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 namespace porting
 {
 
+/*
+       Signal handler (grabs Ctrl-C on POSIX systems)
+*/
+
+void signal_handler_init(void);
+// Returns a pointer to a bool.
+// When the bool is true, program should quit.
+bool * signal_handler_killstatus(void);
+
 /*
        Path of static data directory.
 */
index dc72661fff9c1871f6dc0f38b4be9e475a61b99f..31ebfacbb5d888294f6c09cb65351e38116f5866 100644 (file)
@@ -46,7 +46,12 @@ void * ServerThread::Thread()
        while(getRun())
        {
                try{
-                       m_server->AsyncRunStep();
+                       //TimeTaker timer("AsyncRunStep() + Receive()");
+
+                       {
+                               //TimeTaker timer("AsyncRunStep()");
+                               m_server->AsyncRunStep();
+                       }
                
                        //dout_server<<"Running m_server->Receive()"<<std::endl;
                        m_server->Receive();
@@ -967,7 +972,8 @@ Server::Server(
        m_time_counter(0),
        m_time_of_day_send_timer(0),
        m_uptime(0),
-       m_mapsavedir(mapsavedir)
+       m_mapsavedir(mapsavedir),
+       m_shutdown_requested(false)
 {
        //m_flowwater_timer = 0.0;
        m_liquid_transform_timer = 0.0;
@@ -987,28 +993,62 @@ Server::Server(
 
 Server::~Server()
 {
-       // Save players
+       /*
+               Send shutdown message
+       */
+       {
+               JMutexAutoLock conlock(m_con_mutex);
+               
+               std::wstring line = L"*** Server shutting down";
+
+               /*
+                       Send the message to clients
+               */
+               for(core::map<u16, RemoteClient*>::Iterator
+                       i = m_clients.getIterator();
+                       i.atEnd() == false; i++)
+               {
+                       // Get client and check that it is valid
+                       RemoteClient *client = i.getNode()->getValue();
+                       assert(client->peer_id == i.getNode()->getKey());
+                       if(client->serialization_version == SER_FMT_VER_INVALID)
+                               continue;
+
+                       SendChatMessage(client->peer_id, line);
+               }
+       }
+
+       /*
+               Save players
+       */
        m_env.serializePlayers(m_mapsavedir);
        
-       // Stop threads
+       /*
+               Stop threads
+       */
        stop();
-
-       JMutexAutoLock clientslock(m_con_mutex);
-
-       for(core::map<u16, RemoteClient*>::Iterator
-               i = m_clients.getIterator();
-               i.atEnd() == false; i++)
+       
+       /*
+               Delete clients
+       */
        {
-               /*// Delete player
-               // NOTE: These are removed by env destructor
+               JMutexAutoLock clientslock(m_con_mutex);
+
+               for(core::map<u16, RemoteClient*>::Iterator
+                       i = m_clients.getIterator();
+                       i.atEnd() == false; i++)
                {
-                       u16 peer_id = i.getNode()->getKey();
-                       JMutexAutoLock envlock(m_env_mutex);
-                       m_env.removePlayer(peer_id);
-               }*/
-               
-               // Delete client
-               delete i.getNode()->getValue();
+                       /*// Delete player
+                       // NOTE: These are removed by env destructor
+                       {
+                               u16 peer_id = i.getNode()->getKey();
+                               JMutexAutoLock envlock(m_env_mutex);
+                               m_env.removePlayer(peer_id);
+                       }*/
+                       
+                       // Delete client
+                       delete i.getNode()->getValue();
+               }
        }
 }
 
@@ -1586,39 +1626,9 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
                                        m_time_of_day.get());
                        m_con.Send(peer->id, 0, data, true);
                }
-
+               
                // Send information about server to player in chat
-               {
-                       std::wostringstream os(std::ios_base::binary);
-                       os<<L"# Server: ";
-                       // Uptime
-                       os<<L"uptime="<<m_uptime.get();
-                       // Information about clients
-                       os<<L", clients={";
-                       for(core::map<u16, RemoteClient*>::Iterator
-                               i = m_clients.getIterator();
-                               i.atEnd() == false; i++)
-                       {
-                               // Get client and check that it is valid
-                               RemoteClient *client = i.getNode()->getValue();
-                               assert(client->peer_id == i.getNode()->getKey());
-                               if(client->serialization_version == SER_FMT_VER_INVALID)
-                                       continue;
-                               // Get player
-                               Player *player = m_env.getPlayer(client->peer_id);
-                               // Get name of player
-                               std::wstring name = L"unknown";
-                               if(player != NULL)
-                                       name = narrow_to_wide(player->getName());
-                               // Add name to information string
-                               os<<name<<L",";
-                       }
-                       os<<L"}";
-                       if(((ServerMap*)(&m_env.getMap()))->isSavingEnabled() == false)
-                               os<<" WARNING: Map saving is disabled."<<std::endl;
-                       // Send message
-                       SendChatMessage(peer_id, os.str());
-               }
+               SendChatMessage(peer_id, getStatusString());
                
                // Send information about joining in chat
                {
@@ -2461,29 +2471,115 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
 
                // Get player name of this client
                std::wstring name = narrow_to_wide(player->getName());
-
-               std::wstring line = std::wstring(L"<")+name+L"> "+message;
                
-               dstream<<"CHAT: "<<wide_to_narrow(line)<<std::endl;
-
-               /*
-                       Send the message to all other clients
-               */
-               for(core::map<u16, RemoteClient*>::Iterator
-                       i = m_clients.getIterator();
-                       i.atEnd() == false; i++)
+               // Line to send to players
+               std::wstring line;
+               // Whether to send to the player that sent the line
+               bool send_to_sender = false;
+               // Whether to send to other players
+               bool send_to_others = false;
+               
+               // Parse commands
+               std::wstring commandprefix = L"/#";
+               if(message.substr(0, commandprefix.size()) == commandprefix)
+               {
+                       line += L"Server: ";
+
+                       message = message.substr(commandprefix.size());
+                       // Get player name as narrow string
+                       std::string name_s = player->getName();
+                       // Convert message to narrow string
+                       std::string message_s = wide_to_narrow(message);
+                       // Operator is the single name defined in config.
+                       std::string operator_name = g_settings.get("name");
+                       bool is_operator = (operator_name != "" &&
+                                       wide_to_narrow(name) == operator_name);
+                       bool valid_command = false;
+                       if(message_s == "help")
+                       {
+                               line += L"-!- Available commands: ";
+                               line += L"status ";
+                               if(is_operator)
+                               {
+                                       line += L"shutdown setting ";
+                               }
+                               else
+                               {
+                               }
+                               send_to_sender = true;
+                               valid_command = true;
+                       }
+                       else if(message_s == "status")
+                       {
+                               line = getStatusString();
+                               send_to_sender = true;
+                               valid_command = true;
+                       }
+                       else if(is_operator)
+                       {
+                               if(message_s == "shutdown")
+                               {
+                                       dstream<<DTIME<<" Server: Operator requested shutdown."
+                                                       <<std::endl;
+                                       m_shutdown_requested.set(true);
+                                       
+                                       line += L"*** Server shutting down (operator request)";
+                                       send_to_sender = true;
+                                       valid_command = true;
+                               }
+                               else if(message_s.substr(0,8) == "setting ")
+                               {
+                                       std::string confline = message_s.substr(8);
+                                       g_settings.parseConfigLine(confline);
+                                       line += L"-!- Setting changed.";
+                                       send_to_sender = true;
+                                       valid_command = true;
+                               }
+                       }
+                       
+                       if(valid_command == false)
+                       {
+                               line += L"-!- Invalid command: " + message;
+                               send_to_sender = true;
+                       }
+               }
+               else
                {
-                       // Get client and check that it is valid
-                       RemoteClient *client = i.getNode()->getValue();
-                       assert(client->peer_id == i.getNode()->getKey());
-                       if(client->serialization_version == SER_FMT_VER_INVALID)
-                               continue;
+                       line += L"<";
+                       /*if(is_operator)
+                               line += L"@";*/
+                       line += name;
+                       line += L"> ";
+                       line += message;
+                       send_to_others = true;
+               }
+               
+               if(line != L"")
+               {
+                       dstream<<"CHAT: "<<wide_to_narrow(line)<<std::endl;
 
-                       // Don't send if it's the same one
-                       if(peer_id == client->peer_id)
-                               continue;
+                       /*
+                               Send the message to clients
+                       */
+                       for(core::map<u16, RemoteClient*>::Iterator
+                               i = m_clients.getIterator();
+                               i.atEnd() == false; i++)
+                       {
+                               // Get client and check that it is valid
+                               RemoteClient *client = i.getNode()->getValue();
+                               assert(client->peer_id == i.getNode()->getKey());
+                               if(client->serialization_version == SER_FMT_VER_INVALID)
+                                       continue;
 
-                       SendChatMessage(client->peer_id, line);
+                               // Filter recipient
+                               bool sender_selected = (peer_id == client->peer_id);
+                               if(sender_selected == true && send_to_sender == false)
+                                       continue;
+                               if(sender_selected == false && send_to_others == false)
+                                       continue;
+
+                               SendChatMessage(client->peer_id, line);
+                       }
                }
        }
        else
@@ -2580,6 +2676,7 @@ core::list<PlayerInfo> Server::getPlayerInfo()
        return list;
 }
 
+
 void Server::peerAdded(con::Peer *peer)
 {
        DSTACK(__FUNCTION_NAME);
@@ -3020,6 +3117,8 @@ void Server::SendBlocks(float dtime)
 
        JMutexAutoLock envlock(m_env_mutex);
 
+       //TimeTaker timer("Server::SendBlocks");
+
        core::array<PrioritySortedBlockTransfer> queue;
 
        s32 total_sending = 0;
@@ -3087,6 +3186,39 @@ RemoteClient* Server::getClient(u16 peer_id)
        return n->getValue();
 }
 
+std::wstring Server::getStatusString()
+{
+       std::wostringstream os(std::ios_base::binary);
+       os<<L"# Server: ";
+       // Uptime
+       os<<L"uptime="<<m_uptime.get();
+       // Information about clients
+       os<<L", clients={";
+       for(core::map<u16, RemoteClient*>::Iterator
+               i = m_clients.getIterator();
+               i.atEnd() == false; i++)
+       {
+               // Get client and check that it is valid
+               RemoteClient *client = i.getNode()->getValue();
+               assert(client->peer_id == i.getNode()->getKey());
+               if(client->serialization_version == SER_FMT_VER_INVALID)
+                       continue;
+               // Get player
+               Player *player = m_env.getPlayer(client->peer_id);
+               // Get name of player
+               std::wstring name = L"unknown";
+               if(player != NULL)
+                       name = narrow_to_wide(player->getName());
+               // Add name to information string
+               os<<name<<L",";
+       }
+       os<<L"}";
+       if(((ServerMap*)(&m_env.getMap()))->isSavingEnabled() == false)
+               os<<" WARNING: Map saving is disabled."<<std::endl;
+       return os.str();
+}
+
+
 void setCreativeInventory(Player *player)
 {
        player->resetInventory();
@@ -3455,11 +3587,11 @@ void Server::handlePeerChanges()
        }
 }
 
-void dedicated_server_loop(Server &server)
+void dedicated_server_loop(Server &server, bool &kill)
 {
        DSTACK(__FUNCTION_NAME);
        
-       std::cout<<std::endl;
+       std::cout<<DTIME<<std::endl;
        std::cout<<"========================"<<std::endl;
        std::cout<<"Running dedicated server"<<std::endl;
        std::cout<<"========================"<<std::endl;
@@ -3472,6 +3604,12 @@ void dedicated_server_loop(Server &server)
                sleep_ms(30);
                server.step(0.030);
 
+               if(server.getShutdownRequested() || kill)
+               {
+                       std::cout<<DTIME<<" dedicated_server_loop(): Quitting."<<std::endl;
+                       break;
+               }
+
                static int counter = 0;
                counter--;
                if(counter <= 0)
index d19a440d726a7ad630dcaf7b95cafb23be1528ea..9582c99dd0ffd96e93523359827e23b001af5b20 100644 (file)
@@ -390,15 +390,11 @@ public:
        void Receive();
        void ProcessData(u8 *data, u32 datasize, u16 peer_id);
 
-       /*void Send(u16 peer_id, u16 channelnum,
-                       SharedBuffer<u8> data, bool reliable);*/
-
-       // Environment and Connection must be locked when called
+       // Environment and Connection must be locked when  called
        void SendBlockNoLock(u16 peer_id, MapBlock *block, u8 ver);
        
-       // Environment and Connection must be locked when called
-       //void SendSectorMeta(u16 peer_id, core::list<v2s16> ps, u8 ver);
-
+       //
+       
        core::list<PlayerInfo> getPlayerInfo();
 
        u32 getDayNightRatio()
@@ -412,7 +408,12 @@ public:
                else
                        return 1000;
        }
-       
+
+       bool getShutdownRequested()
+       {
+               return m_shutdown_requested.get();
+       }
+
 private:
 
        // Virtual methods from con::PeerHandler.
@@ -432,7 +433,10 @@ private:
        
        // When called, connection mutex should be locked
        RemoteClient* getClient(u16 peer_id);
-
+       
+       // Connection must be locked when called
+       std::wstring getStatusString();
+       
        /*
                Get a player from memory or creates one.
                If player is already connected, return NULL
@@ -490,7 +494,7 @@ private:
        float m_time_of_day_send_timer;
        
        MutexedVariable<double> m_uptime;
-
+       
        enum PeerChangeType
        {
                PEER_ADDED,
@@ -508,14 +512,18 @@ private:
 
        std::string m_mapsavedir;
 
+       MutexedVariable<bool> m_shutdown_requested;
+
        friend class EmergeThread;
        friend class RemoteClient;
 };
 
 /*
-       Runs a simple dedicated server loop
+       Runs a simple dedicated server loop.
+
+       Shuts down when run is set to false.
 */
-void dedicated_server_loop(Server &server);
+void dedicated_server_loop(Server &server, bool &run);
 
 #endif
 
index 1c301d4f59af8dce1cd79d76a38c5e53aecb8798..254b1f28aade159080df0d2f6eaa26d6e037e2c6 100644 (file)
@@ -98,7 +98,6 @@ std::ostream *derr_server_ptr = &dstream;
 std::ostream *dout_client_ptr = &dstream;
 std::ostream *derr_client_ptr = &dstream;
 
-
 /*
        gettime.h implementation
 */
@@ -129,6 +128,9 @@ int main(int argc, char *argv[])
 
        DSTACK(__FUNCTION_NAME);
 
+       porting::signal_handler_init();
+       bool &kill = *porting::signal_handler_killstatus();
+       
        porting::initializePaths();
 
        initializeMaterialProperties();
@@ -251,6 +253,11 @@ int main(int argc, char *argv[])
        srand(time(0));
        mysrand(time(0));
 
+       // Initialize stuff
+       
+       init_mapnode();
+       init_mineral();
+
        /*
                Run unit tests
        */
@@ -260,11 +267,6 @@ int main(int argc, char *argv[])
                run_tests();
        }
 
-       // Initialize stuff
-       
-       init_mapnode();
-       init_mineral();
-
        /*
                Check parameters
        */
@@ -308,9 +310,9 @@ int main(int argc, char *argv[])
        // Create server
        Server server(map_dir.c_str());
        server.start(port);
-       
+
        // Run server
-       dedicated_server_loop(server);
+       dedicated_server_loop(server, kill);
        
        } //try
        catch(con::PeerNotFoundException &e)
index e5b22a978570420ce7e454ad7b15137de561a003..1de902787987e72acfdd280e0ffbfe2f8bf835cb 100644 (file)
@@ -192,7 +192,7 @@ struct TestMapNode
                // Transparency
                n.d = CONTENT_AIR;
                assert(n.light_propagates() == true);
-               n.d = 0;
+               n.d = CONTENT_STONE;
                assert(n.light_propagates() == false);
        }
 };
index 46277cd4240ec2ffcb33c28de40ecd3828cbe69d..8c81aba9170c8c8f1f3a5b7e72646dc5760dc50d 100644 (file)
@@ -802,9 +802,15 @@ struct ValueSpec
 class Settings
 {
 public:
+       Settings()
+       {
+               m_mutex.Init();
+       }
 
        void writeLines(std::ostream &os)
        {
+               JMutexAutoLock lock(m_mutex);
+               
                for(core::map<std::string, std::string>::Iterator
                                i = m_settings.getIterator();
                                i.atEnd() == false; i++)
@@ -817,6 +823,8 @@ public:
 
        bool parseConfigLine(const std::string &line)
        {
+               JMutexAutoLock lock(m_mutex);
+               
                std::string trimmedline = trim(line);
                
                // Ignore comments
@@ -899,6 +907,8 @@ public:
                        core::list<std::string> &dst,
                        core::map<std::string, bool> &updated)
        {
+               JMutexAutoLock lock(m_mutex);
+               
                if(is.eof())
                        return false;
                
@@ -981,6 +991,8 @@ public:
                        }
                }
                
+               JMutexAutoLock lock(m_mutex);
+               
                // Write stuff back
                {
                        std::ofstream os(filename);
@@ -1087,21 +1099,29 @@ public:
 
        void set(std::string name, std::string value)
        {
+               JMutexAutoLock lock(m_mutex);
+               
                m_settings[name] = value;
        }
 
        void setDefault(std::string name, std::string value)
        {
+               JMutexAutoLock lock(m_mutex);
+               
                m_defaults[name] = value;
        }
 
        bool exists(std::string name)
        {
+               JMutexAutoLock lock(m_mutex);
+               
                return (m_settings.find(name) || m_defaults.find(name));
        }
 
        std::string get(std::string name)
        {
+               JMutexAutoLock lock(m_mutex);
+               
                core::map<std::string, std::string>::Node *n;
                n = m_settings.find(name);
                if(n == NULL)
@@ -1139,7 +1159,7 @@ public:
        bool getBoolAsk(std::string name, std::string question, bool def)
        {
                // If it is in settings
-               if(m_settings.find(name))
+               if(exists(name))
                        return getBool(name);
                
                std::string s;
@@ -1167,7 +1187,7 @@ public:
        u16 getU16Ask(std::string name, std::string question, u16 def)
        {
                // If it is in settings
-               if(m_settings.find(name))
+               if(exists(name))
                        return getU16(name);
                
                std::string s;
@@ -1238,12 +1258,17 @@ public:
 
        void clear()
        {
+               JMutexAutoLock lock(m_mutex);
+               
                m_settings.clear();
                m_defaults.clear();
        }
 
        Settings & operator+=(Settings &other)
        {
+               JMutexAutoLock lock(m_mutex);
+               JMutexAutoLock lock2(other.m_mutex);
+               
                if(&other == this)
                        return *this;
 
@@ -1267,6 +1292,9 @@ public:
 
        Settings & operator=(Settings &other)
        {
+               JMutexAutoLock lock(m_mutex);
+               JMutexAutoLock lock2(other.m_mutex);
+               
                if(&other == this)
                        return *this;
 
@@ -1279,6 +1307,8 @@ public:
 private:
        core::map<std::string, std::string> m_settings;
        core::map<std::string, std::string> m_defaults;
+       // All methods that access m_settings/m_defaults directly should lock this.
+       JMutex m_mutex;
 };
 
 /*