Merged CiaranG's fence graphic updates (ugh, well, it worked, i guess, kind of.)...
authorPerttu Ahola <celeron55@gmail.com>
Wed, 1 Jun 2011 23:37:49 +0000 (02:37 +0300)
committerPerttu Ahola <celeron55@gmail.com>
Wed, 1 Jun 2011 23:37:49 +0000 (02:37 +0300)
28 files changed:
.hgtags
CMakeLists.txt
doc/changelog.txt
minetest.conf.example
src/auth.cpp
src/auth.h
src/base64.cpp
src/client.cpp
src/defaultsettings.cpp
src/environment.cpp
src/environment.h
src/game.cpp
src/guiPasswordChange.cpp
src/guiPasswordChange.h
src/main.cpp
src/main.h
src/map.cpp
src/map.h
src/mapblock.cpp
src/nodemetadata.cpp
src/profiler.h [new file with mode: 0644]
src/server.cpp
src/server.h
src/servercommand.cpp
src/servercommand.h
src/servermain.cpp
src/utility.cpp
src/utility.h

diff --git a/.hgtags b/.hgtags
index 984460c6d594a0b7991aa1c87edb72d67a7f15d9..cf8df124be6a35779bca061e5c4768e21c2af6e6 100644 (file)
--- a/.hgtags
+++ b/.hgtags
@@ -7,3 +7,4 @@ e3c3c8e27bbc8c9b61710517a78944deb1c61696 110211211322
 9b05d4bfee9312aef4182fa6f63b4237368cec34 0.2.20110529_0
 6fa0a8b40406aa567f8fa84b5e2045a7e3762c1d 0.2.20110529_1
 cf6dd618ef0b7514c81ae87749733b5a328fc763 0.2.20110529_2
+96efc17b4cd92aacbe947b520a6ba91727d42f03 0.2.20110602_0
index 85743e73a744b0485df07f28073738817e25e4dc..c1074e6d37602e69a56302df1f08f36b16c4e1d8 100644 (file)
@@ -9,7 +9,7 @@ project(minetest)
 
 set(VERSION_MAJOR 0)
 set(VERSION_MINOR 2)
-set(VERSION_PATCH 20110529_2)
+set(VERSION_PATCH 20110602_0)
 set(VERSION_STRING "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}")
 
 # Configuration options
index e02019783d6242751013ed54968a4ef947f2264a..5a01b6bc48a23cfdacf158d30a5ed9731ffbd0cf 100644 (file)
@@ -3,6 +3,11 @@ Minetest-c55 changelog
 This should contain all the major changes.
 For minor stuff, refer to the commit log of the repository.
 
+2011-06-02:
+- Password crash on windows fixed
+- Optimized server CPU usage a lot
+- Furnaces now work also while players are not near to them
+
 2011-05-29:
 - Optimized smooth lighting
 - A number of small fixes
index 1a1dbe0fc85e604f52aabead8929d5f8730259f2..743186853b2cc69cb641c90c0332d545ab2d4034 100644 (file)
 # Server side stuff
 #
 
-# Set to true to enable experimental features
-# (varies from version to version, see wiki)
-#enable_experimental = false
-
 # Map directory (everything in the world is stored here)
 #map-dir = /home/palle/custom_map
 
 # Gives some stuff to players at the beginning
 #give_initial_stuff = false
 
+# Set to true to enable experimental features
+# (varies from version to version, see wiki)
+#enable_experimental = false
+
+# Profiler data print interval. 0 = disable.
+#profiler_print_interval = 10
+
 # Player and object positions are sent at intervals specified by this
 #objectdata_inverval = 0.2
 
index 49985e6978950b3c87c3dc188993426794f65d73..5d61243c693e357e279da5d6ee6f06d7160a0960 100644 (file)
@@ -77,7 +77,8 @@ u64 stringToPrivs(std::string str)
 }
 
 AuthManager::AuthManager(const std::string &authfilepath):
-               m_authfilepath(authfilepath)
+               m_authfilepath(authfilepath),
+               m_modified(false)
 {
        m_mutex.Init();
        
@@ -138,6 +139,8 @@ void AuthManager::load()
                ad.privs = privs;
                m_authdata[name] = ad;
        }
+
+       m_modified = false;
 }
 
 void AuthManager::save()
@@ -162,6 +165,8 @@ void AuthManager::save()
                AuthData ad = i.getNode()->getValue();
                os<<name<<":"<<ad.pwd<<":"<<privsToString(ad.privs)<<"\n";
        }
+
+       m_modified = false;
 }
 
 bool AuthManager::exists(const std::string &username)
@@ -180,6 +185,8 @@ void AuthManager::set(const std::string &username, AuthData ad)
        JMutexAutoLock lock(m_mutex);
        
        m_authdata[username] = ad;
+
+       m_modified = true;
 }
 
 void AuthManager::add(const std::string &username)
@@ -187,6 +194,8 @@ void AuthManager::add(const std::string &username)
        JMutexAutoLock lock(m_mutex);
        
        m_authdata[username] = AuthData();
+
+       m_modified = true;
 }
 
 std::string AuthManager::getPassword(const std::string &username)
@@ -214,6 +223,8 @@ void AuthManager::setPassword(const std::string &username,
        AuthData ad = n->getValue();
        ad.pwd = password;
        n->setValue(ad);
+
+       m_modified = true;
 }
 
 u64 AuthManager::getPrivs(const std::string &username)
@@ -240,5 +251,14 @@ void AuthManager::setPrivs(const std::string &username, u64 privs)
        AuthData ad = n->getValue();
        ad.privs = privs;
        n->setValue(ad);
+
+       m_modified = true;
 }
 
+bool AuthManager::isModified()
+{
+       JMutexAutoLock lock(m_mutex);
+       return m_modified;
+}
+
+
index 472409d46391a626250daf479f157ff69399a4c3..62dced2a38e0f6b6e481b3cfdaa41c2d7a399eb4 100644 (file)
@@ -89,10 +89,12 @@ public:
                        const std::string &password);
        u64 getPrivs(const std::string &username);
        void setPrivs(const std::string &username, u64 privs);
+       bool isModified();
 private:
        JMutex m_mutex;
        std::string m_authfilepath;
        core::map<std::string, AuthData> m_authdata;
+       bool m_modified;
 };
 
 #endif
index 2a863d161a00e5fcf6c56caf0c088ef6914f1a9e..0dfba501303aa4606232c5f667f35f6ea895b86c 100644 (file)
@@ -71,9 +71,10 @@ std::string base64_encode(unsigned char const* bytes_to_encode, unsigned int in_
 
     for (j = 0; (j < i + 1); j++)
       ret += base64_chars[char_array_4[j]];
-
-    while((i++ < 3))
-      ret += '=';
+       
+       // Don't pad it with =
+    /*while((i++ < 3))
+      ret += '=';*/
 
   }
 
index 79bbd8021ca64ba60b2429e67b5ab9a8c4f37c8a..e494056f27dcaeaeb56b75e4082df1423a32012d 100644 (file)
@@ -306,8 +306,14 @@ void Client::step(float dtime)
                        SharedBuffer<u8> data(2+1+PLAYERNAME_SIZE+PASSWORD_SIZE);
                        writeU16(&data[0], TOSERVER_INIT);
                        writeU8(&data[2], SER_FMT_VER_HIGHEST);
+
                        memset((char*)&data[3], 0, PLAYERNAME_SIZE);
                        snprintf((char*)&data[3], PLAYERNAME_SIZE, "%s", myplayer->getName());
+
+                       /*dstream<<"Client: password hash is \""<<m_password<<"\""
+                                       <<std::endl;*/
+
+                       memset((char*)&data[23], 0, PASSWORD_SIZE);
                        snprintf((char*)&data[23], PASSWORD_SIZE, "%s", m_password.c_str());
 
                        // Send as unreliable
index 6fcdc1dbb30c006f8fbedf29c10c99e3c5188640..73f22a7f77128bdde417d55890ecce4bc492c7cf 100644 (file)
@@ -74,12 +74,13 @@ void set_default_settings()
        g_settings.setDefault("give_initial_stuff", "false");
        g_settings.setDefault("default_password", "");
        g_settings.setDefault("default_privs", "build, shout");
+       g_settings.setDefault("profiler_print_interval", "0");
 
        g_settings.setDefault("objectdata_interval", "0.2");
        g_settings.setDefault("active_object_range", "2");
        g_settings.setDefault("max_simultaneous_block_sends_per_client", "1");
        //g_settings.setDefault("max_simultaneous_block_sends_per_client", "2");
-       g_settings.setDefault("max_simultaneous_block_sends_server_total", "4");
+       g_settings.setDefault("max_simultaneous_block_sends_server_total", "8");
        g_settings.setDefault("max_block_send_distance", "8");
        g_settings.setDefault("max_block_generate_distance", "8");
        g_settings.setDefault("time_send_interval", "20");
index 36c754d5717b5a153279ffc868196e5d769671c0..f5f20d0e5e0b7832889e9c60f0013bb92058735c 100644 (file)
@@ -729,6 +729,16 @@ void ServerEnvironment::step(float dtime)
                        // Activate stored objects
                        activateObjects(block);
 
+                       // Run node metadata
+                       bool changed = block->m_node_metadata.step((float)dtime_s);
+                       if(changed)
+                       {
+                               MapEditEvent event;
+                               event.type = MEET_BLOCK_NODE_METADATA_CHANGED;
+                               event.p = p;
+                               m_map->dispatchEvent(&event);
+                       }
+
                        // TODO: Do something
                        // TODO: Implement usage of ActiveBlockModifier
                        
@@ -762,8 +772,10 @@ void ServerEnvironment::step(float dtime)
        /*
                Mess around in active blocks
        */
-       if(m_active_blocks_test_interval.step(dtime, 10.0))
+       if(m_active_blocks_nodemetadata_interval.step(dtime, 1.0))
        {
+               float dtime = 1.0;
+
                for(core::map<v3s16, bool>::Iterator
                                i = m_active_blocks.m_list.getIterator();
                                i.atEnd()==false; i++)
@@ -779,7 +791,38 @@ void ServerEnvironment::step(float dtime)
                        
                        // Set current time as timestamp
                        block->setTimestamp(m_game_time);
+
+                       // Run node metadata
+                       bool changed = block->m_node_metadata.step(dtime);
+                       if(changed)
+                       {
+                               MapEditEvent event;
+                               event.type = MEET_BLOCK_NODE_METADATA_CHANGED;
+                               event.p = p;
+                               m_map->dispatchEvent(&event);
+                       }
+               }
+       }
+       if(m_active_blocks_test_interval.step(dtime, 10.0))
+       {
+               //float dtime = 10.0;
+
+               for(core::map<v3s16, bool>::Iterator
+                               i = m_active_blocks.m_list.getIterator();
+                               i.atEnd()==false; i++)
+               {
+                       v3s16 p = i.getNode()->getKey();
                        
+                       /*dstream<<"Server: Block ("<<p.X<<","<<p.Y<<","<<p.Z
+                                       <<") being handled"<<std::endl;*/
+
+                       MapBlock *block = m_map->getBlockNoCreateNoEx(p);
+                       if(block==NULL)
+                               continue;
+                       
+                       // Set current time as timestamp
+                       block->setTimestamp(m_game_time);
+
                        /*
                                Do stuff!
 
@@ -801,8 +844,11 @@ void ServerEnvironment::step(float dtime)
                        {
                                v3s16 p = p0 + block->getPosRelative();
                                MapNode n = block->getNodeNoEx(p0);
-                               // Test something:
-                               // Convert mud under proper lighting to grass
+
+                               /*
+                                       Test something:
+                                       Convert mud under proper lighting to grass
+                               */
                                if(n.d == CONTENT_MUD)
                                {
                                        if(myrand()%20 == 0)
index f5cce59339ab01451f8655edf85aeb652f1d19ce..b4f2a64caeb465ee5614b5a89452b44f17a3fe26 100644 (file)
@@ -246,6 +246,7 @@ private:
        ActiveBlockList m_active_blocks;
        IntervalLimiter m_active_blocks_management_interval;
        IntervalLimiter m_active_blocks_test_interval;
+       IntervalLimiter m_active_blocks_nodemetadata_interval;
        // Time from the beginning of the game in seconds.
        // Incremented in step().
        u32 m_game_time;
index 6932b45f1f6468fc37bb75b22f103ca50c658a13..e8e6cb71f042f6364e6e2da0f7300346a39a5ebc 100644 (file)
@@ -903,6 +903,10 @@ void the_game(
 
        bool first_loop_after_window_activation = true;
 
+       // TODO: Convert the static interval timers to these
+       // Interval limiter for profiler
+       IntervalLimiter m_profiler_interval;
+
        // Time is in milliseconds
        // NOTE: getRealTime() causes strange problems in wine (imprecision?)
        // NOTE: So we have to use getTime() and call run()s between them
@@ -1089,6 +1093,21 @@ void the_game(
                        }
                }
 
+               /*
+                       Profiler
+               */
+               float profiler_print_interval =
+                               g_settings.getFloat("profiler_print_interval");
+               if(profiler_print_interval != 0)
+               {
+                       if(m_profiler_interval.step(0.030, profiler_print_interval))
+                       {
+                               dstream<<"Profiler:"<<std::endl;
+                               g_profiler.print(dstream);
+                               g_profiler.clear();
+                       }
+               }
+
                /*
                        Direct handling of user input
                */
index 98b11b43214495c168e95a9591f11765be6e74b1..ec1cd029ab321165df02086198bc0b71240316b1 100644 (file)
@@ -1,21 +1,19 @@
 /*
-Minetest-c55
-Copyright (C) 2010-11 celeron55, Perttu Ahola <celeron55@gmail.com>
+Part of Minetest-c55
+Copyright (C) 2011 celeron55, Perttu Ahola <celeron55@gmail.com>
 Copyright (C) 2011 Ciaran Gultnieks <ciaran@ciarang.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.
+Permission to use, copy, modify, and distribute this software for any
+purpose with or without fee is hereby granted, provided that the above
+copyright notice and this permission notice appear in all copies.
+
+THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */
 
 #include "guiPasswordChange.h"
index defac31139542d5324c5aea69e3ceee996111b8b..1748baadeafdedf010b65b0713046d8e1b1b48a0 100644 (file)
@@ -1,21 +1,19 @@
 /*
-Minetest-c55
+Part of Minetest-c55
 Copyright (C) 2010-11 celeron55, Perttu Ahola <celeron55@gmail.com>
 Copyright (C) 2011 Ciaran Gultnieks <ciaran@ciarang.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.
+Permission to use, copy, modify, and distribute this software for any
+purpose with or without fee is hereby granted, provided that the above
+copyright notice and this permission notice appear in all copies.
+
+THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */
 
 #ifndef GUIPASSWORDCHANGE_HEADER
index 3d342e5960646e0dc8cc2196ee0c76eedd68325c..2cde3b302f66765b7cefdb83f514cd1027d072b7 100644 (file)
@@ -215,6 +215,8 @@ FIXME: Server sometimes goes into some infinite PeerNotFoundException loop
 FIXME: The new optimized map sending doesn't sometimes send enough blocks\r
        from big caves and such\r
 \r
+* Take player's walking direction into account in GetNextBlocks\r
+\r
 Environment:\r
 ------------\r
 \r
@@ -308,6 +310,9 @@ Making it more portable:
 Stuff to do before release:\r
 ---------------------------\r
 \r
+Fixes to the current release:\r
+-----------------------------\r
+\r
 Stuff to do after release:\r
 ---------------------------\r
 - Make sure server handles removing grass when a block is placed (etc)\r
@@ -386,6 +391,9 @@ Settings g_settings;
 // This is located in defaultsettings.cpp\r
 extern void set_default_settings();\r
 \r
+// Global profiler\r
+Profiler g_profiler;\r
+\r
 /*\r
        Random stuff\r
 */\r
@@ -436,7 +444,14 @@ std::ostream *derr_client_ptr = &dstream;
 class TimeGetter\r
 {\r
 public:\r
-       TimeGetter(IrrlichtDevice *device):\r
+       virtual u32 getTime() = 0;\r
+};\r
+\r
+// A precise irrlicht one\r
+class IrrlichtTimeGetter: public TimeGetter\r
+{\r
+public:\r
+       IrrlichtTimeGetter(IrrlichtDevice *device):\r
                m_device(device)\r
        {}\r
        u32 getTime()\r
@@ -448,8 +463,18 @@ public:
 private:\r
        IrrlichtDevice *m_device;\r
 };\r
+// Not so precise one which works without irrlicht\r
+class SimpleTimeGetter: public TimeGetter\r
+{\r
+public:\r
+       u32 getTime()\r
+       {\r
+               return porting::getTimeMs();\r
+       }\r
+};\r
 \r
 // A pointer to a global instance of the time getter\r
+// TODO: why?\r
 TimeGetter *g_timegetter = NULL;\r
 \r
 u32 getTimeMs()\r
@@ -1208,6 +1233,9 @@ int main(int argc, char *argv[])
        {\r
                DSTACK("Dedicated server branch");\r
 \r
+               // Create time getter\r
+               g_timegetter = new SimpleTimeGetter();\r
+               \r
                // Create server\r
                Server server(map_dir.c_str());\r
                server.start(port);\r
@@ -1290,7 +1318,7 @@ int main(int argc, char *argv[])
        device = device;\r
        \r
        // Create time getter\r
-       g_timegetter = new TimeGetter(device);\r
+       g_timegetter = new IrrlichtTimeGetter(device);\r
        \r
        // Create game callback for menus\r
        g_gamecallback = new MainGameCallback(device);\r
@@ -1497,6 +1525,8 @@ int main(int argc, char *argv[])
                                g_settings.set("creative_mode", itos(menudata.creative_mode));\r
                                g_settings.set("enable_damage", itos(menudata.enable_damage));\r
                                \r
+                               // NOTE: These are now checked server side; no need to do it\r
+                               //       here, so let's not do it here.\r
                                /*// Check for valid parameters, restart menu if invalid.\r
                                if(playername == "")\r
                                {\r
index fcf150f874fea51c81c64976aad7bc6486827fa1..450525c26e2d53f37433f2e3ad1c6eefdabed259 100644 (file)
@@ -28,6 +28,10 @@ extern Settings g_settings;
 #include "tile.h"
 extern ITextureSource *g_texturesource;
 
+// Global profiler
+#include "profiler.h"
+extern Profiler g_profiler;
+
 // Debug streams
 
 #include <fstream>
index a49de3c4600b3dc4c39d6d7096fde1aa6ffd8917..f9809e9fdb85b5745f1f77a24be24bb5593c6e0d 100644 (file)
@@ -5692,9 +5692,9 @@ void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass)
                        p_nodes_min.Y / MAP_BLOCKSIZE - 1,
                        p_nodes_min.Z / MAP_BLOCKSIZE - 1);
        v3s16 p_blocks_max(
-                       p_nodes_max.X / MAP_BLOCKSIZE + 1,
-                       p_nodes_max.Y / MAP_BLOCKSIZE + 1,
-                       p_nodes_max.Z / MAP_BLOCKSIZE + 1);
+                       p_nodes_max.X / MAP_BLOCKSIZE,
+                       p_nodes_max.Y / MAP_BLOCKSIZE,
+                       p_nodes_max.Z / MAP_BLOCKSIZE);
        
        u32 vertex_count = 0;
        
index 09154547cf6240bf5bd44ea2aff0a9c39df8b2db..6f7ac0d3bfc5a591f6ac5d2dc99ea47ed5642261 100644 (file)
--- a/src/map.h
+++ b/src/map.h
@@ -46,8 +46,14 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #define MAPTYPE_CLIENT 2
 
 enum MapEditEventType{
+       // Node added (changed from air or something else to something)
        MEET_ADDNODE,
+       // Node removed (changed to air)
        MEET_REMOVENODE,
+       // Node metadata of block changed (not knowing which node exactly)
+       // p stores block coordinate
+       MEET_BLOCK_NODE_METADATA_CHANGED,
+       // Anything else
        MEET_OTHER
 };
 
index 7adb8c2dfce9e3470d41908cf3ad219f9330844e..e31596b9c2b85c86185fba7e487e290cc1c243f8 100644 (file)
@@ -540,10 +540,10 @@ void updateFastFaceRow(
                
                v3s16 p_next;
                
-               bool next_makes_face;
+               bool next_makes_face = false;
                v3s16 next_p_corrected;
                v3s16 next_face_dir_corrected;
-               u8 next_lights[4];
+               u8 next_lights[4] = {0,0,0,0};
                TileSpec next_tile;
                
                // If at last position, there is nothing to compare to and
index 308a3385432a5126ee6e4010158e24dbd4f6bdda..f9468e4fa14f2a3dcc21f08788fdb734b2d24712 100644 (file)
@@ -268,91 +268,100 @@ void FurnaceNodeMetadata::inventoryModified()
 }
 bool FurnaceNodeMetadata::step(float dtime)
 {
+       if(dtime > 60.0)
+               dstream<<"Furnace stepping a long time ("<<dtime<<")"<<std::endl;
        // Update at a fixed frequency
-       const float interval = 0.5;
+       const float interval = 2.0;
        m_step_accumulator += dtime;
-       if(m_step_accumulator < interval)
-               return false;
-       m_step_accumulator -= interval;
-       dtime = interval;
-
-       //dstream<<"Furnace step dtime="<<dtime<<std::endl;
-       
-       InventoryList *dst_list = m_inventory->getList("dst");
-       assert(dst_list);
-
-       InventoryList *src_list = m_inventory->getList("src");
-       assert(src_list);
-       InventoryItem *src_item = src_list->getItem(0);
-       
-       // Start only if there are free slots in dst, so that it can
-       // accomodate any result item
-       if(dst_list->getFreeSlots() > 0 && src_item && src_item->isCookable())
-       {
-               m_src_totaltime = 3;
-       }
-       else
+       bool changed = false;
+       while(m_step_accumulator > interval)
        {
-               m_src_time = 0;
-               m_src_totaltime = 0;
-       }
+               m_step_accumulator -= interval;
+               dtime = interval;
 
-       if(m_fuel_time < m_fuel_totaltime)
-       {
-               //dstream<<"Furnace is active"<<std::endl;
-               m_fuel_time += dtime;
-               m_src_time += dtime;
-               if(m_src_time >= m_src_totaltime && m_src_totaltime > 0.001
-                               && src_item)
+               //dstream<<"Furnace step dtime="<<dtime<<std::endl;
+               
+               InventoryList *dst_list = m_inventory->getList("dst");
+               assert(dst_list);
+
+               InventoryList *src_list = m_inventory->getList("src");
+               assert(src_list);
+               InventoryItem *src_item = src_list->getItem(0);
+               
+               // Start only if there are free slots in dst, so that it can
+               // accomodate any result item
+               if(dst_list->getFreeSlots() > 0 && src_item && src_item->isCookable())
+               {
+                       m_src_totaltime = 3;
+               }
+               else
                {
-                       InventoryItem *cookresult = src_item->createCookResult();
-                       dst_list->addItem(cookresult);
-                       src_list->decrementMaterials(1);
                        m_src_time = 0;
                        m_src_totaltime = 0;
                }
-               return true;
-       }
-       
-       if(src_item == NULL || m_src_totaltime < 0.001)
-       {
-               return false;
-       }
-       
-       bool changed = false;
 
-       //dstream<<"Furnace is out of fuel"<<std::endl;
+               if(m_fuel_time < m_fuel_totaltime)
+               {
+                       //dstream<<"Furnace is active"<<std::endl;
+                       m_fuel_time += dtime;
+                       m_src_time += dtime;
+                       if(m_src_time >= m_src_totaltime && m_src_totaltime > 0.001
+                                       && src_item)
+                       {
+                               InventoryItem *cookresult = src_item->createCookResult();
+                               dst_list->addItem(cookresult);
+                               src_list->decrementMaterials(1);
+                               m_src_time = 0;
+                               m_src_totaltime = 0;
+                       }
+                       changed = true;
+                       continue;
+               }
+               
+               if(src_item == NULL || m_src_totaltime < 0.001)
+               {
+                       continue;
+               }
+               
+               //dstream<<"Furnace is out of fuel"<<std::endl;
 
-       InventoryList *fuel_list = m_inventory->getList("fuel");
-       assert(fuel_list);
-       InventoryItem *fuel_item = fuel_list->getItem(0);
+               InventoryList *fuel_list = m_inventory->getList("fuel");
+               assert(fuel_list);
+               InventoryItem *fuel_item = fuel_list->getItem(0);
 
-       if(ItemSpec(ITEM_MATERIAL, CONTENT_TREE).checkItem(fuel_item))
-       {
-               m_fuel_totaltime = 10;
-               m_fuel_time = 0;
-               fuel_list->decrementMaterials(1);
-               changed = true;
-       }
-       else if(ItemSpec(ITEM_MATERIAL, CONTENT_WOOD).checkItem(fuel_item))
-       {
-               m_fuel_totaltime = 5;
-               m_fuel_time = 0;
-               fuel_list->decrementMaterials(1);
-               changed = true;
-       }
-       else if(ItemSpec(ITEM_CRAFT, "lump_of_coal").checkItem(fuel_item))
-       {
-               m_fuel_totaltime = 10;
-               m_fuel_time = 0;
-               fuel_list->decrementMaterials(1);
-               changed = true;
-       }
-       else
-       {
-               //dstream<<"No fuel found"<<std::endl;
+               if(ItemSpec(ITEM_MATERIAL, CONTENT_TREE).checkItem(fuel_item))
+               {
+                       m_fuel_totaltime = 30;
+                       m_fuel_time = 0;
+                       fuel_list->decrementMaterials(1);
+                       changed = true;
+               }
+               else if(ItemSpec(ITEM_MATERIAL, CONTENT_WOOD).checkItem(fuel_item))
+               {
+                       m_fuel_totaltime = 30/4;
+                       m_fuel_time = 0;
+                       fuel_list->decrementMaterials(1);
+                       changed = true;
+               }
+               else if(ItemSpec(ITEM_CRAFT, "Stick").checkItem(fuel_item))
+               {
+                       m_fuel_totaltime = 30/4/4;
+                       m_fuel_time = 0;
+                       fuel_list->decrementMaterials(1);
+                       changed = true;
+               }
+               else if(ItemSpec(ITEM_CRAFT, "lump_of_coal").checkItem(fuel_item))
+               {
+                       m_fuel_totaltime = 40;
+                       m_fuel_time = 0;
+                       fuel_list->decrementMaterials(1);
+                       changed = true;
+               }
+               else
+               {
+                       //dstream<<"No fuel found"<<std::endl;
+               }
        }
-
        return changed;
 }
 
diff --git a/src/profiler.h b/src/profiler.h
new file mode 100644 (file)
index 0000000..a30e34a
--- /dev/null
@@ -0,0 +1,131 @@
+/*
+Minetest-c55
+Copyright (C) 2011 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 PROFILER_HEADER
+#define PROFILER_HEADER
+
+#include "common_irrlicht.h"
+#include <string>
+#include "utility.h"
+#include <jmutex.h>
+#include <jmutexautolock.h>
+
+/*
+       Time profiler
+*/
+
+class Profiler
+{
+public:
+       Profiler()
+       {
+               m_mutex.Init();
+       }
+
+       void add(const std::string &name, u32 duration)
+       {
+               JMutexAutoLock lock(m_mutex);
+               core::map<std::string, u32>::Node *n = m_data.find(name);
+               if(n == NULL)
+               {
+                       m_data[name] = duration;
+               }
+               else
+               {
+                       n->setValue(n->getValue()+duration);
+               }
+       }
+
+       void clear()
+       {
+               JMutexAutoLock lock(m_mutex);
+               for(core::map<std::string, u32>::Iterator
+                               i = m_data.getIterator();
+                               i.atEnd() == false; i++)
+               {
+                       i.getNode()->setValue(0);
+               }
+       }
+
+       void print(std::ostream &o)
+       {
+               JMutexAutoLock lock(m_mutex);
+               for(core::map<std::string, u32>::Iterator
+                               i = m_data.getIterator();
+                               i.atEnd() == false; i++)
+               {
+                       std::string name = i.getNode()->getKey();
+                       o<<name<<": ";
+                       s32 clampsize = 40;
+                       s32 space = clampsize-name.size();
+                       for(s32 j=0; j<space; j++)
+                       {
+                               if(j%2 == 0 && j < space - 1)
+                                       o<<"-";
+                               else
+                                       o<<" ";
+                       }
+                       o<<i.getNode()->getValue();
+                       o<<std::endl;
+               }
+       }
+
+private:
+       JMutex m_mutex;
+       core::map<std::string, u32> m_data;
+};
+
+class ScopeProfiler
+{
+public:
+       ScopeProfiler(Profiler *profiler, const std::string &name):
+               m_profiler(profiler),
+               m_name(name),
+               m_timer(NULL)
+       {
+               if(m_profiler)
+                       m_timer = new TimeTaker(m_name.c_str());
+       }
+       // name is copied
+       ScopeProfiler(Profiler *profiler, const char *name):
+               m_profiler(profiler),
+               m_name(name),
+               m_timer(NULL)
+       {
+               if(m_profiler)
+                       m_timer = new TimeTaker(m_name.c_str());
+       }
+       ~ScopeProfiler()
+       {
+               if(m_timer)
+               {
+                       u32 duration = m_timer->stop(true);
+                       if(m_profiler)
+                               m_profiler->add(m_name, duration);
+                       delete m_timer;
+               }
+       }
+private:
+       Profiler *m_profiler;
+       std::string m_name;
+       TimeTaker *m_timer;
+};
+
+#endif
+
index 56874c46c3c8442f4c49ffbc23bf1eb3af0b710f..96fcc0d0757a1aa8a78dab959895c4d6b590aba7 100644 (file)
@@ -312,11 +312,14 @@ void RemoteClient::GetNextBlocks(Server *server, float dtime,
        TimeTaker timer("RemoteClient::GetNextBlocks", &timer_result);*/
        
        // Increment timers
-       m_nearest_unsent_reset_timer += dtime;
        m_nothing_to_send_pause_timer -= dtime;
        
        if(m_nothing_to_send_pause_timer >= 0)
+       {
+               // Keep this reset
+               m_nearest_unsent_reset_timer = 0;
                return;
+       }
 
        // Won't send anything if already sending
        if(m_blocks_sending.size() >= g_settings.getU16
@@ -326,14 +329,21 @@ void RemoteClient::GetNextBlocks(Server *server, float dtime,
                return;
        }
 
+       //TimeTaker timer("RemoteClient::GetNextBlocks");
+       
        Player *player = server->m_env.getPlayer(peer_id);
 
        assert(player != NULL);
 
        v3f playerpos = player->getPosition();
        v3f playerspeed = player->getSpeed();
+       v3f playerspeeddir(0,0,0);
+       if(playerspeed.getLength() > 1.0*BS)
+               playerspeeddir = playerspeed / playerspeed.getLength();
+       // Predict to next block
+       v3f playerpos_predicted = playerpos + playerspeeddir*MAP_BLOCKSIZE*BS;
 
-       v3s16 center_nodepos = floatToInt(playerpos, BS);
+       v3s16 center_nodepos = floatToInt(playerpos_predicted, BS);
 
        v3s16 center = getNodeBlockPos(center_nodepos);
        
@@ -344,6 +354,9 @@ void RemoteClient::GetNextBlocks(Server *server, float dtime,
        camera_dir.rotateYZBy(player->getPitch());
        camera_dir.rotateXZBy(player->getYaw());
 
+       /*dstream<<"camera_dir=("<<camera_dir.X<<","<<camera_dir.Y<<","
+                       <<camera_dir.Z<<")"<<std::endl;*/
+
        /*
                Get the starting value of the block finder radius.
        */
@@ -356,11 +369,18 @@ void RemoteClient::GetNextBlocks(Server *server, float dtime,
 
        /*dstream<<"m_nearest_unsent_reset_timer="
                        <<m_nearest_unsent_reset_timer<<std::endl;*/
-       if(m_nearest_unsent_reset_timer > 5.0)
+                       
+       // This has to be incremented only when the nothing to send pause
+       // is not active
+       m_nearest_unsent_reset_timer += dtime;
+       
+       // Reset periodically to avoid possible bugs or other mishaps
+       if(m_nearest_unsent_reset_timer > 10.0)
        {
                m_nearest_unsent_reset_timer = 0;
                m_nearest_unsent_d = 0;
-               //dstream<<"Resetting m_nearest_unsent_d"<<std::endl;
+               /*dstream<<"Resetting m_nearest_unsent_d for "
+                               <<server->getPlayerName(peer_id)<<std::endl;*/
        }
 
        //s16 last_nearest_unsent_d = m_nearest_unsent_d;
@@ -402,11 +422,22 @@ void RemoteClient::GetNextBlocks(Server *server, float dtime,
        s16 d_max = g_settings.getS16("max_block_send_distance");
        s16 d_max_gen = g_settings.getS16("max_block_generate_distance");
        
+       // Don't loop very much at a time
+       if(d_max > d_start+1)
+               d_max = d_start+1;
+       /*if(d_max_gen > d_start+2)
+               d_max_gen = d_start+2;*/
+       
        //dstream<<"Starting from "<<d_start<<std::endl;
 
        bool sending_something = false;
 
-       for(s16 d = d_start; d <= d_max; d++)
+       bool no_blocks_found_for_sending = true;
+
+       bool queue_is_full = false;
+       
+       s16 d;
+       for(d = d_start; d <= d_max; d++)
        {
                //dstream<<"RemoteClient::SendBlocks(): d="<<d<<std::endl;
                
@@ -451,7 +482,10 @@ void RemoteClient::GetNextBlocks(Server *server, float dtime,
 
                        // Don't select too many blocks for sending
                        if(num_blocks_selected >= max_simul_dynamic)
-                               goto queue_full;
+                       {
+                               queue_is_full = true;
+                               goto queue_full_break;
+                       }
                        
                        // Don't send blocks that are currently being transferred
                        if(m_blocks_sending.find(p) != NULL)
@@ -513,6 +547,8 @@ void RemoteClient::GetNextBlocks(Server *server, float dtime,
                        }
 #endif
 
+                       //dstream<<"d="<<d<<std::endl;
+                       
                        /*
                                Don't generate or send if not in sight
                        */
@@ -527,7 +563,9 @@ void RemoteClient::GetNextBlocks(Server *server, float dtime,
                        */
                        {
                                if(m_blocks_sent.find(p) != NULL)
+                               {
                                        continue;
+                               }
                        }
 
                        /*
@@ -539,11 +577,14 @@ void RemoteClient::GetNextBlocks(Server *server, float dtime,
                        bool block_is_invalid = false;
                        if(block != NULL)
                        {
+                               // Block is dummy if data doesn't exist.
+                               // It means it has been not found from disk and not generated
                                if(block->isDummy())
                                {
                                        surely_not_found_on_disk = true;
                                }
-
+                               
+                               // Block is valid if lighting is up-to-date and data exists
                                if(block->isValid() == false)
                                {
                                        block_is_invalid = true;
@@ -564,8 +605,8 @@ void RemoteClient::GetNextBlocks(Server *server, float dtime,
                                        If block is not close, don't send it unless it is near
                                        ground level.
 
-                                       Block is not near ground level if night-time mesh
-                                       doesn't differ from day-time mesh.
+                                       Block is near ground level if night-time mesh
+                                       differs from day-time mesh.
                                */
                                if(d > 3)
                                {
@@ -586,14 +627,16 @@ void RemoteClient::GetNextBlocks(Server *server, float dtime,
                        }
 
                        /*
-                               Record the lowest d from which a block has been
+                               Record the lowest d from which a block has been
                                found being not sent and possibly to exist
                        */
-                       if(new_nearest_unsent_d == -1 || d < new_nearest_unsent_d)
+                       if(no_blocks_found_for_sending)
                        {
                                if(generate == true)
                                        new_nearest_unsent_d = d;
                        }
+
+                       no_blocks_found_for_sending = false;
                                        
                        /*
                                Add inexistent block to emerge queue.
@@ -633,20 +676,30 @@ void RemoteClient::GetNextBlocks(Server *server, float dtime,
                        sending_something = true;
                }
        }
-queue_full:
+queue_full_break:
 
-       if(new_nearest_unsent_d != -1)
+       //dstream<<"Stopped at "<<d<<std::endl;
+       
+       if(no_blocks_found_for_sending)
        {
-               m_nearest_unsent_d = new_nearest_unsent_d;
+               if(queue_is_full == false)
+                       new_nearest_unsent_d = d;
        }
 
+       if(new_nearest_unsent_d != -1)
+               m_nearest_unsent_d = new_nearest_unsent_d;
+
        if(sending_something == false)
        {
                m_nothing_to_send_counter++;
-               if(m_nothing_to_send_counter >= 3)
+               if((s16)m_nothing_to_send_counter >=
+                               g_settings.getS16("max_block_send_distance"))
                {
                        // Pause time in seconds
-                       m_nothing_to_send_pause_timer = 2.0;
+                       m_nothing_to_send_pause_timer = 1.0;
+                       /*dstream<<"nothing to send to "
+                                       <<server->getPlayerName(peer_id)
+                                       <<" (d="<<d<<")"<<std::endl;*/
                }
        }
        else
@@ -1130,12 +1183,16 @@ void Server::AsyncRunStep()
                dtime = m_step_dtime;
        }
        
-       // Send blocks to clients
-       SendBlocks(dtime);
+       {
+               ScopeProfiler sp(&g_profiler, "Server: selecting and sending "
+                               "blocks to clients");
+               // Send blocks to clients
+               SendBlocks(dtime);
+       }
        
        if(dtime < 0.001)
                return;
-       
+
        //dstream<<"Server steps "<<dtime<<std::endl;
        //dstream<<"Server::AsyncRunStep(): dtime="<<dtime<<std::endl;
        
@@ -1196,12 +1253,14 @@ void Server::AsyncRunStep()
        {
                // Process connection's timeouts
                JMutexAutoLock lock2(m_con_mutex);
+               ScopeProfiler sp(&g_profiler, "Server: connection timeout processing");
                m_con.RunTimeouts(dtime);
        }
        
        {
                // This has to be called so that the client list gets synced
                // with the peer list of the connection
+               ScopeProfiler sp(&g_profiler, "Server: peer change handling");
                handlePeerChanges();
        }
 
@@ -1209,6 +1268,7 @@ void Server::AsyncRunStep()
                // Step environment
                // This also runs Map's timers
                JMutexAutoLock lock(m_env_mutex);
+               ScopeProfiler sp(&g_profiler, "Server: environment step");
                m_env.step(dtime);
        }
        
@@ -1225,7 +1285,9 @@ void Server::AsyncRunStep()
                m_liquid_transform_timer -= 1.00;
                
                JMutexAutoLock lock(m_env_mutex);
-               
+
+               ScopeProfiler sp(&g_profiler, "Server: liquid transform");
+
                core::map<v3s16, MapBlock*> modified_blocks;
                m_env.getMap().transformLiquids(modified_blocks);
 #if 0          
@@ -1298,10 +1360,11 @@ void Server::AsyncRunStep()
        */
        {
                //dstream<<"Server: Checking added and deleted active objects"<<std::endl;
-
                JMutexAutoLock envlock(m_env_mutex);
                JMutexAutoLock conlock(m_con_mutex);
-               
+
+               ScopeProfiler sp(&g_profiler, "Server: checking added and deleted objects");
+
                // Radius inside which objects are active
                s16 radius = 32;
 
@@ -1446,6 +1509,8 @@ void Server::AsyncRunStep()
                JMutexAutoLock envlock(m_env_mutex);
                JMutexAutoLock conlock(m_con_mutex);
 
+               ScopeProfiler sp(&g_profiler, "Server: sending object messages");
+
                // Key = object id
                // Value = data sent by object
                core::map<u16, core::list<ActiveObjectMessage>* > buffered_messages;
@@ -1572,6 +1637,11 @@ void Server::AsyncRunStep()
                                dstream<<"Server: MEET_REMOVENODE"<<std::endl;
                                sendRemoveNode(event->p, event->already_known_by_peer);
                        }
+                       else if(event->type == MEET_BLOCK_NODE_METADATA_CHANGED)
+                       {
+                               dstream<<"Server: MEET_BLOCK_NODE_METADATA_CHANGED"<<std::endl;
+                               setBlockNotSent(event->p);
+                       }
                        else if(event->type == MEET_OTHER)
                        {
                                dstream<<"WARNING: Server: MEET_OTHER not implemented"
@@ -1598,6 +1668,9 @@ void Server::AsyncRunStep()
                {
                        JMutexAutoLock lock1(m_env_mutex);
                        JMutexAutoLock lock2(m_con_mutex);
+
+                       ScopeProfiler sp(&g_profiler, "Server: sending mbo positions");
+
                        SendObjectData(counter);
 
                        counter = 0.0;
@@ -1606,15 +1679,20 @@ void Server::AsyncRunStep()
        
        /*
                Step node metadata
+               TODO: Move to ServerEnvironment and utilize active block stuff
        */
-       {
+       /*{
                //TimeTaker timer("Step node metadata");
 
                JMutexAutoLock envlock(m_env_mutex);
                JMutexAutoLock conlock(m_con_mutex);
-               
+
+               ScopeProfiler sp(&g_profiler, "Server: stepping node metadata");
+
                core::map<v3s16, MapBlock*> changed_blocks;
                m_env.getMap().nodeMetadataStep(dtime, changed_blocks);
+               
+               // Use setBlockNotSent
 
                for(core::map<v3s16, MapBlock*>::Iterator
                                i = changed_blocks.getIterator();
@@ -1630,7 +1708,7 @@ void Server::AsyncRunStep()
                                client->SetBlockNotSent(block->getPos());
                        }
                }
-       }
+       }*/
                
        /*
                Trigger emergethread (it somehow gets to a non-triggered but
@@ -1655,8 +1733,11 @@ void Server::AsyncRunStep()
                {
                        counter = 0.0;
 
+                       ScopeProfiler sp(&g_profiler, "Server: saving stuff");
+
                        // Auth stuff
-                       m_authmanager.save();
+                       if(m_authmanager.isModified())
+                               m_authmanager.save();
                        
                        // Map
                        JMutexAutoLock lock(m_env_mutex);
@@ -1842,7 +1923,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
                        checkpwd = g_settings.get("default_password");
                }
                
-               if(password != checkpwd)
+               if(password != checkpwd && checkpwd != "")
                {
                        derr_server<<DTIME<<"Server: peer_id="<<peer_id
                                        <<": supplied invalid password for "
@@ -3581,6 +3662,17 @@ void Server::sendAddNode(v3s16 p, MapNode n, u16 ignore_id,
        }
 }
 
+void Server::setBlockNotSent(v3s16 p)
+{
+       for(core::map<u16, RemoteClient*>::Iterator
+               i = m_clients.getIterator();
+               i.atEnd()==false; i++)
+       {
+               RemoteClient *client = i.getNode()->getValue();
+               client->SetBlockNotSent(p);
+       }
+}
+
 void Server::SendBlockNoLock(u16 peer_id, MapBlock *block, u8 ver)
 {
        DSTACK(__FUNCTION_NAME);
@@ -3646,20 +3738,24 @@ void Server::SendBlocks(float dtime)
        core::array<PrioritySortedBlockTransfer> queue;
 
        s32 total_sending = 0;
-
-       for(core::map<u16, RemoteClient*>::Iterator
-               i = m_clients.getIterator();
-               i.atEnd() == false; i++)
+       
        {
-               RemoteClient *client = i.getNode()->getValue();
-               assert(client->peer_id == i.getNode()->getKey());
+               ScopeProfiler sp(&g_profiler, "Server: selecting blocks for sending");
 
-               total_sending += client->SendingCount();
-               
-               if(client->serialization_version == SER_FMT_VER_INVALID)
-                       continue;
-               
-               client->GetNextBlocks(this, dtime, queue);
+               for(core::map<u16, RemoteClient*>::Iterator
+                       i = m_clients.getIterator();
+                       i.atEnd() == false; i++)
+               {
+                       RemoteClient *client = i.getNode()->getValue();
+                       assert(client->peer_id == i.getNode()->getKey());
+
+                       total_sending += client->SendingCount();
+                       
+                       if(client->serialization_version == SER_FMT_VER_INVALID)
+                               continue;
+                       
+                       client->GetNextBlocks(this, dtime, queue);
+               }
        }
 
        // Sort.
@@ -4531,25 +4627,48 @@ void dedicated_server_loop(Server &server, bool &kill)
 {
        DSTACK(__FUNCTION_NAME);
        
-       std::cout<<DTIME<<std::endl;
-       std::cout<<"========================"<<std::endl;
-       std::cout<<"Running dedicated server"<<std::endl;
-       std::cout<<"========================"<<std::endl;
-       std::cout<<std::endl;
+       dstream<<DTIME<<std::endl;
+       dstream<<"========================"<<std::endl;
+       dstream<<"Running dedicated server"<<std::endl;
+       dstream<<"========================"<<std::endl;
+       dstream<<std::endl;
+
+       IntervalLimiter m_profiler_interval;
 
        for(;;)
        {
                // This is kind of a hack but can be done like this
                // because server.step() is very light
-               sleep_ms(30);
+               {
+                       ScopeProfiler sp(&g_profiler, "dedicated server sleep");
+                       sleep_ms(30);
+               }
                server.step(0.030);
 
                if(server.getShutdownRequested() || kill)
                {
-                       std::cout<<DTIME<<" dedicated_server_loop(): Quitting."<<std::endl;
+                       dstream<<DTIME<<" dedicated_server_loop(): Quitting."<<std::endl;
                        break;
                }
 
+               /*
+                       Profiler
+               */
+               float profiler_print_interval =
+                               g_settings.getFloat("profiler_print_interval");
+               if(profiler_print_interval != 0)
+               {
+                       if(m_profiler_interval.step(0.030, profiler_print_interval))
+                       {
+                               dstream<<"Profiler:"<<std::endl;
+                               g_profiler.print(dstream);
+                               g_profiler.clear();
+                       }
+               }
+               
+               /*
+                       Player info
+               */
                static int counter = 0;
                counter--;
                if(counter <= 0)
@@ -4562,10 +4681,10 @@ void dedicated_server_loop(Server &server, bool &kill)
                        u32 sum = PIChecksum(list);
                        if(sum != sum_old)
                        {
-                               std::cout<<DTIME<<"Player info:"<<std::endl;
+                               dstream<<DTIME<<"Player info:"<<std::endl;
                                for(i=list.begin(); i!=list.end(); i++)
                                {
-                                       i->PrintLine(&std::cout);
+                                       i->PrintLine(&dstream);
                                }
                        }
                        sum_old = sum;
index 7b73e476c54530a563434bea71c00c3b5335a720..791ecdec770009dcd9ead6b2347709efdd284399 100644 (file)
@@ -480,15 +480,17 @@ private:
                Additionally, if far_players!=NULL, players further away than
                far_d_nodes are ignored and their peer_ids are added to far_players
        */
+       // Envlock and conlock should be locked when calling these
        void sendRemoveNode(v3s16 p, u16 ignore_id=0,
                        core::list<u16> *far_players=NULL, float far_d_nodes=100);
        void sendAddNode(v3s16 p, MapNode n, u16 ignore_id=0,
                        core::list<u16> *far_players=NULL, float far_d_nodes=100);
+       void setBlockNotSent(v3s16 p);
        
        // Environment and Connection must be locked when called
        void SendBlockNoLock(u16 peer_id, MapBlock *block, u8 ver);
        
-       // Sends blocks to clients
+       // Sends blocks to clients (locks env and con on its own)
        void SendBlocks(float dtime);
 
        /*
@@ -500,6 +502,15 @@ private:
        // When called, connection mutex should be locked
        RemoteClient* getClient(u16 peer_id);
        
+       // When called, environment mutex should be locked
+       std::string getPlayerName(u16 peer_id)
+       {
+               Player *player = m_env.getPlayer(peer_id);
+               if(player == NULL)
+                       return "[id="+itos(peer_id);
+               return player->getName();
+       }
+
        /*
                Get a player from memory or creates one.
                If player is already connected, return NULL
@@ -627,6 +638,8 @@ private:
        */
        u16 m_ignore_map_edit_events_peer_id;
 
+       Profiler *m_profiler;
+
        friend class EmergeThread;
        friend class RemoteClient;
 };
index e05578b3994d8dbdd56a2626286f4000cf1695d0..333e29084cd85ddec67496005de0b03b353ccd2a 100644 (file)
@@ -1,24 +1,21 @@
 /*
-Minetest-c55
-Copyright (C) 2010-2011 celeron55, Perttu Ahola <celeron55@gmail.com>
+Part of Minetest-c55
+Copyright (C) 2010-11 celeron55, Perttu Ahola <celeron55@gmail.com>
 Copyright (C) 2011 Ciaran Gultnieks <ciaran@ciarang.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.
+Permission to use, copy, modify, and distribute this software for any
+purpose with or without fee is hereby granted, provided that the above
+copyright notice and this permission notice appear in all copies.
+
+THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */
 
-
 #include "servercommand.h"
 #include "utility.h"
 
index 058fbe65ba246c43aea3ee89a2fd467e9e4bce63..9013bc2a6da15779ebba1f00d08849f436fe4c99 100644 (file)
@@ -1,21 +1,19 @@
 /*
-Minetest-c55
-Copyright (C) 2010-2011 celeron55, Perttu Ahola <celeron55@gmail.com>
+Part of Minetest-c55
+Copyright (C) 2010-11 celeron55, Perttu Ahola <celeron55@gmail.com>
 Copyright (C) 2011 Ciaran Gultnieks <ciaran@ciarang.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.
+Permission to use, copy, modify, and distribute this software for any
+purpose with or without fee is hereby granted, provided that the above
+copyright notice and this permission notice appear in all copies.
+
+THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */
 
 #ifndef SERVERCOMMAND_HEADER
index f3b17000c4d9285d93b0604c0e7c400227a00bbc..f83e2ae76da8cefe6ff953a0fdbf361fdd99b128 100644 (file)
@@ -79,6 +79,9 @@ Settings g_settings;
 
 extern void set_default_settings();
 
+// Global profiler
+Profiler g_profiler;
+
 // A dummy thing
 ITextureSource *g_texturesource = NULL;
 
index 186881c5acc2ba59a794301f457248a202a2a4d4..0721100cb98e845871e033aaf5920fcb9a624a14 100644 (file)
@@ -229,10 +229,10 @@ std::string translatePassword(std::string playername, std::wstring password)
        if(password.length() == 0)
                return "";
 
-       std::string slt=playername + wide_to_narrow(password);
-       SHA1 *sha1 = new SHA1();
-       sha1->addBytes(slt.c_str(), slt.length());
-       unsigned char *digest = sha1->getDigest();
+       std::string slt = playername + wide_to_narrow(password);
+       SHA1 sha1;
+       sha1.addBytes(slt.c_str(), slt.length());
+       unsigned char *digest = sha1.getDigest();
        std::string pwd = base64_encode(digest, 20);
        free(digest);
        return pwd;
index f18d3127841522732f0c514adc47790bca804351..534aea483e17843ce88d68f67b5c2b33a920aca2 100644 (file)
@@ -244,6 +244,9 @@ inline f32 readF1000(std::istream &is)
 {
        char buf[2];
        is.read(buf, 2);
+       // TODO: verify if this gets rid of the valgrind warning
+       //if(is.gcount() != 2)
+       //      return 0;
        return readF1000((u8*)buf);
 }