working time-of-day sending from server to client
authorPerttu Ahola <celeron55@gmail.com>
Mon, 20 Dec 2010 12:04:31 +0000 (14:04 +0200)
committerPerttu Ahola <celeron55@gmail.com>
Mon, 20 Dec 2010 12:04:31 +0000 (14:04 +0200)
Makefile
minetest.conf.example
src/client.cpp
src/client.h
src/clientserver.h
src/defaultsettings.cpp [new file with mode: 0644]
src/main.cpp
src/server.cpp
src/server.h
src/servermain.cpp

index 08107718c1acda64db4d0061ac45262faab9b657..38a59c2dedf48429368fe3f44057912615b09bc2 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -2,18 +2,18 @@
 # It's usually sufficient to change just the target name and source file list\r
 # and be sure that CXX is set to a valid compiler\r
 TARGET = test\r
-SOURCE_FILES = guiPauseMenu.cpp mapnode.cpp tile.cpp voxel.cpp mapblockobject.cpp inventory.cpp debug.cpp serialization.cpp light.cpp filesys.cpp connection.cpp environment.cpp client.cpp server.cpp socket.cpp mapblock.cpp mapsector.cpp heightmap.cpp map.cpp player.cpp utility.cpp main.cpp test.cpp\r
+SOURCE_FILES = guiPauseMenu.cpp defaultsettings.cpp mapnode.cpp tile.cpp voxel.cpp mapblockobject.cpp inventory.cpp debug.cpp serialization.cpp light.cpp filesys.cpp connection.cpp environment.cpp client.cpp server.cpp socket.cpp mapblock.cpp mapsector.cpp heightmap.cpp map.cpp player.cpp utility.cpp main.cpp test.cpp\r
 SOURCES = $(addprefix src/, $(SOURCE_FILES))\r
-BUILD_DIR = build\r
+BUILD_DIR = build/\r
 OBJECTS = $(addprefix $(BUILD_DIR)/, $(SOURCE_FILES:.cpp=.o))\r
 #OBJECTS = $(SOURCES:.cpp=.o)\r
 \r
 FAST_TARGET = fasttest\r
 \r
 SERVER_TARGET = server\r
-SERVER_SOURCE_FILES = mapnode.cpp voxel.cpp mapblockobject.cpp inventory.cpp debug.cpp serialization.cpp light.cpp filesys.cpp connection.cpp environment.cpp server.cpp socket.cpp mapblock.cpp mapsector.cpp heightmap.cpp map.cpp player.cpp utility.cpp servermain.cpp test.cpp\r
+SERVER_SOURCE_FILES = defaultsettings.cpp mapnode.cpp voxel.cpp mapblockobject.cpp inventory.cpp debug.cpp serialization.cpp light.cpp filesys.cpp connection.cpp environment.cpp server.cpp socket.cpp mapblock.cpp mapsector.cpp heightmap.cpp map.cpp player.cpp utility.cpp servermain.cpp test.cpp\r
 SERVER_SOURCES = $(addprefix src/, $(SERVER_SOURCE_FILES))\r
-SERVER_BUILD_DIR = serverbuild\r
+SERVER_BUILD_DIR = serverbuild/\r
 SERVER_OBJECTS = $(addprefix $(SERVER_BUILD_DIR)/, $(SERVER_SOURCE_FILES:.cpp=.o))\r
 #SERVER_OBJECTS = $(SERVER_SOURCES:.cpp=.o)\r
 \r
@@ -57,13 +57,13 @@ SERVER_DESTPATH = bin/$(SERVER_TARGET)$(SUF)
 \r
 # Build commands\r
 \r
-all_linux all_win32: make_build_dir $(DESTPATH)\r
-fast_linux: make_build_dir $(FAST_DESTPATH)\r
-server_linux: make_server_build_dir $(SERVER_DESTPATH)\r
+all_linux all_win32: $(BUILD_DIR) $(DESTPATH)\r
+fast_linux: $(BUILD_DIR) $(FAST_DESTPATH)\r
+server_linux: $(SERVER_BUILD_DIR) $(SERVER_DESTPATH)\r
 \r
-make_build_dir:\r
+$(BUILD_DIR):\r
        mkdir -p $(BUILD_DIR)\r
-make_server_build_dir:\r
+$(SERVER_BUILD_DIR):\r
        mkdir -p $(SERVER_BUILD_DIR)\r
 \r
 $(DESTPATH): $(OBJECTS)\r
index df0ff1e7c5bfb4f2ae5fc58e451cb23d8a2360f1..20392e56d6270a0ab99dabedff394a80d7ea31a9 100644 (file)
 # Note that this gets applied at map generation time
 #endless_water = true
 
+# 20 min/day
+#time_speed = 72
+# 1 min/day
+#time_speed = 1440
+
+#time_send_interval = 5
+
index 37482ba912116fabdcb01bdc0d78c368b42c0067..b612c9c44c2465446b744b7fd18002ec72810138 100644 (file)
@@ -91,10 +91,7 @@ Client::Client(
        m_server_ser_ver(SER_FMT_VER_INVALID),
        m_step_dtime(0.0),
        m_inventory_updated(false),
-       m_time(0),
-       m_time_counter(0.0)
-       //m_daynight_i(0)
-       //m_daynight_ratio(1000)
+       m_time_of_day(0)
 {
        m_packetcounter_timer = 0.0;
        m_delete_unused_sectors_timer = 0.0;
@@ -165,48 +162,29 @@ void Client::step(float dtime)
                Day/night
        */
        {
-               m_time_counter += dtime;
-               int seconds = (int)m_time_counter;
-               m_time_counter -= (float)seconds;
-               m_time += seconds;
-               if(seconds > 0)
+               s32 d = 8;
+               s32 t = (((m_time_of_day.get() + 24000/d/2)%24000)/(24000/d));
+               s32 dn = 0;
+               if(t == d/4 || t == (d-d/4))
+                       dn = 1;
+               else if(t < d/4 || t > (d-d/4))
+                       dn = 2;
+               else
+                       dn = 0;
+
+               u32 dr = 1000;
+               if(dn == 0)
+                       dr = 1000;
+               if(dn == 1)
+                       dr = 600;
+               if(dn == 2)
+                       dr = 300;
+               
+               if(dr != m_env.getDayNightRatio())
                {
-                       //dstream<<"m_time="<<m_time<<std::endl;
-                       /*JMutexAutoLock envlock(m_env_mutex);
-                       u32 dr = 500+500*sin((float)((m_time/10)%7)/7.*2.*PI);
-                       if(dr != m_env.getDayNightRatio())
-                       {
-                               dstream<<"dr="<<dr<<std::endl;
-                               m_env.setDayNightRatio(dr);
-                               m_env.expireMeshes();
-                       }*/
-#if 1
-                       s32 d = 4;
-                       s32 t = (m_time/10)%d;
-                       s32 dn = 0;
-                       if(t == d/2-1 || t == d-1)
-                               dn = 1;
-                       else if(t < d/2-1)
-                               dn = 0;
-                       else
-                               dn = 2;
-
-                       u32 dr = 1000;
-                       if(dn == 0)
-                               dr = 1000;
-                       if(dn == 1)
-                               dr = 600;
-                       if(dn == 2)
-                               dr = 300;
-#else
-                       u32 dr = 1000;
-#endif
-                       if(dr != m_env.getDayNightRatio())
-                       {
-                               dstream<<"dr="<<dr<<std::endl;
-                               m_env.setDayNightRatio(dr);
-                               m_env.expireMeshes(true);
-                       }
+                       //dstream<<"dr="<<dr<<std::endl;
+                       m_env.setDayNightRatio(dr);
+                       m_env.expireMeshes(true);
                }
        }
 
@@ -1034,6 +1012,16 @@ void Client::ProcessData(u8 *data, u32 datasize, u16 sender_peer_id)
 
                } //envlock
        }
+       else if(command == TOCLIENT_TIME_OF_DAY)
+       {
+               if(datasize < 4)
+                       return;
+               
+               u16 time = readU16(&data[2]);
+               time = time % 24000;
+               m_time_of_day.set(time);
+               //dstream<<"Client: time="<<time<<std::endl;
+       }
        // Default to queueing it (for slow commands)
        else
        {
index 4720bd72035436db5eed826c9dbd767d34a93991..a1ee3f762b62b0c122c310f537cff3e618a720c9 100644 (file)
@@ -290,9 +290,8 @@ private:
 
        PacketCounter m_packetcounter;
        
-       // Access these only in main thread.
-       u32 m_time;
-       float m_time_counter;
+       // Received from the server. 0-23999
+       MutexedVariable<u32> m_time_of_day;
        
        // 0 <= m_daynight_i < DAYNIGHT_CACHE_COUNT
        //s32 m_daynight_i;
index 4526083dabe4972a4954e1f0442be5554f6be86e..5e919b2f7b94de19155617cdc091ac730be74a7c 100644 (file)
@@ -20,6 +20,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #ifndef CLIENTSERVER_HEADER
 #define CLIENTSERVER_HEADER
 
+#include "utility.h"
+
 #define PROTOCOL_ID 0x4f457403
 
 enum ToClientCommand
@@ -90,6 +92,12 @@ enum ToClientCommand
                        v3s16 blockpos
                        block objects
        */
+
+       TOCLIENT_TIME_OF_DAY = 0x29,
+       /*
+               u16 command
+               u16 time (0-23999)
+       */
 };
 
 enum ToServerCommand
@@ -185,8 +193,13 @@ enum ToServerCommand
        */
 };
 
-// Flags for TOSERVER_GETBLOCK
-#define TOSERVER_GETBLOCK_FLAG_OPTIONAL (1<<0)
+inline SharedBuffer<u8> makePacket_TOCLIENT_TIME_OF_DAY(u16 time)
+{
+       SharedBuffer<u8> data(2+2);
+       writeU16(&data[0], TOCLIENT_TIME_OF_DAY);
+       writeU16(&data[2], time);
+       return data;
+}
 
 #endif
 
diff --git a/src/defaultsettings.cpp b/src/defaultsettings.cpp
new file mode 100644 (file)
index 0000000..2dbbaad
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+Minetest-c55
+Copyright (C) 2010 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.
+*/
+
+#include "utility.h"
+
+extern Settings g_settings;
+
+void set_default_settings()
+{
+       // Client stuff
+       g_settings.setDefault("wanted_fps", "30");
+       g_settings.setDefault("fps_max", "60");
+       g_settings.setDefault("viewing_range_nodes_max", "300");
+       g_settings.setDefault("viewing_range_nodes_min", "35");
+       g_settings.setDefault("screenW", "");
+       g_settings.setDefault("screenH", "");
+       g_settings.setDefault("host_game", "");
+       g_settings.setDefault("port", "");
+       g_settings.setDefault("address", "");
+       g_settings.setDefault("name", "");
+       g_settings.setDefault("random_input", "false");
+       g_settings.setDefault("client_delete_unused_sectors_timeout", "1200");
+       g_settings.setDefault("enable_fog", "true");
+
+       // Server stuff
+       g_settings.setDefault("creative_mode", "false");
+       g_settings.setDefault("heightmap_blocksize", "32");
+       g_settings.setDefault("height_randmax", "constant 50.0");
+       g_settings.setDefault("height_randfactor", "constant 0.6");
+       g_settings.setDefault("height_base", "linear 0 0 0");
+       g_settings.setDefault("plants_amount", "1.0");
+       g_settings.setDefault("ravines_amount", "1.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_server_total", "4");
+       g_settings.setDefault("disable_water_climb", "true");
+       g_settings.setDefault("endless_water", "true");
+       g_settings.setDefault("max_block_send_distance", "5");
+       g_settings.setDefault("max_block_generate_distance", "4");
+       g_settings.setDefault("time_send_interval", "20");
+       g_settings.setDefault("time_speed", "144");
+}
+
index b747da66aa9cdee6174211337cf4b79651bb0a6f..7d146835fe8911c931da1f7d609656d0beb0349d 100644 (file)
@@ -172,10 +172,6 @@ TODO: Check what goes wrong with caching map to disk (Kray)
 \r
 TODO: Remove LazyMeshUpdater. It is not used as supposed.\r
 \r
-TODO: Node cracking animation when digging\r
-      - TODO: A way to generate new textures by combining textures\r
-         - TODO: Mesh update to fetch cracked faces from the former\r
-\r
 TODO: Add server unused sector deletion settings to settings\r
 \r
 TODO: TOSERVER_LEAVE\r
@@ -183,6 +179,10 @@ TODO: TOSERVER_LEAVE
 Doing now:\r
 ======================================================================\r
 \r
+TODO: Node cracking animation when digging\r
+      - TODO: A way to generate new textures by combining textures\r
+         - TODO: Mesh update to fetch cracked faces from the former\r
+\r
 ======================================================================\r
 \r
 */\r
@@ -298,41 +298,7 @@ bool g_viewing_range_all = false;
 \r
 Settings g_settings;\r
 \r
-// Sets default settings\r
-void set_default_settings()\r
-{\r
-       // Client stuff\r
-       g_settings.setDefault("wanted_fps", "30");\r
-       g_settings.setDefault("fps_max", "60");\r
-       g_settings.setDefault("viewing_range_nodes_max", "300");\r
-       g_settings.setDefault("viewing_range_nodes_min", "35");\r
-       g_settings.setDefault("screenW", "");\r
-       g_settings.setDefault("screenH", "");\r
-       g_settings.setDefault("host_game", "");\r
-       g_settings.setDefault("port", "");\r
-       g_settings.setDefault("address", "");\r
-       g_settings.setDefault("name", "");\r
-       g_settings.setDefault("random_input", "false");\r
-       g_settings.setDefault("client_delete_unused_sectors_timeout", "1200");\r
-       g_settings.setDefault("enable_fog", "true");\r
-\r
-       // Server stuff\r
-       g_settings.setDefault("creative_mode", "false");\r
-       g_settings.setDefault("heightmap_blocksize", "32");\r
-       g_settings.setDefault("height_randmax", "constant 50.0");\r
-       g_settings.setDefault("height_randfactor", "constant 0.6");\r
-       g_settings.setDefault("height_base", "linear 0 0 0");\r
-       g_settings.setDefault("plants_amount", "1.0");\r
-       g_settings.setDefault("ravines_amount", "1.0");\r
-       g_settings.setDefault("objectdata_interval", "0.2");\r
-       g_settings.setDefault("active_object_range", "2");\r
-       g_settings.setDefault("max_simultaneous_block_sends_per_client", "1");\r
-       g_settings.setDefault("max_simultaneous_block_sends_server_total", "4");\r
-       g_settings.setDefault("disable_water_climb", "true");\r
-       g_settings.setDefault("endless_water", "true");\r
-       g_settings.setDefault("max_block_send_distance", "5");\r
-       g_settings.setDefault("max_block_generate_distance", "4");\r
-}\r
+extern void set_default_settings();\r
 \r
 /*\r
        Random stuff\r
index a2dfc8269790cbbd8b43aba9114453a73a2bd937..7260e21d317a0c804d7485232532b9e5aff76ac6 100644 (file)
@@ -31,6 +31,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "constants.h"
 #include "voxel.h"
 
+#define BLOCK_EMERGE_FLAG_FROMDISK (1<<0)
+
 void * ServerThread::Thread()
 {
        ThreadStarted();
@@ -121,7 +123,7 @@ void * EmergeThread::Thread()
 
                                // Check flags
                                u8 flags = i.getNode()->getValue();
-                               if((flags & TOSERVER_GETBLOCK_FLAG_OPTIONAL) == false)
+                               if((flags & BLOCK_EMERGE_FLAG_FROMDISK) == false)
                                        optional = false;
                                
                        }
@@ -541,7 +543,7 @@ void RemoteClient::GetNextBlocks(Server *server, float dtime,
                                        
                                        u8 flags = 0;
                                        if(generate == false)
-                                               flags |= TOSERVER_GETBLOCK_FLAG_OPTIONAL;
+                                               flags |= BLOCK_EMERGE_FLAG_FROMDISK;
                                        
                                        server->m_emerge_queue.addBlock(peer_id, p, flags);
                                        server->m_emergethread.trigger();
@@ -757,7 +759,7 @@ void RemoteClient::SendObjectData(
                                m_num_blocks_in_emerge_queue.m_value++;*/
                                
                                // Add to queue as an anonymous fetch from disk
-                               u8 flags = TOSERVER_GETBLOCK_FLAG_OPTIONAL;
+                               u8 flags = BLOCK_EMERGE_FLAG_FROMDISK;
                                server->m_emerge_queue.addBlock(0, p, flags);
                                server->m_emergethread.trigger();
                        }
@@ -926,7 +928,10 @@ Server::Server(
        m_env(new ServerMap(mapsavedir, hm_params, map_params), dout_server),
        m_con(PROTOCOL_ID, 512, CONNECTION_TIMEOUT, this),
        m_thread(this),
-       m_emergethread(this)
+       m_emergethread(this),
+       m_time_of_day(12000),
+       m_time_counter(0),
+       m_time_of_day_send_timer(0)
 {
        m_flowwater_timer = 0.0;
        m_print_info_timer = 0.0;
@@ -1025,6 +1030,45 @@ void Server::AsyncRunStep()
                JMutexAutoLock lock1(m_step_dtime_mutex);
                m_step_dtime -= dtime;
        }
+       
+       /*
+               Update m_time_of_day
+       */
+       {
+               m_time_counter += dtime;
+               f32 speed = g_settings.getFloat("time_speed") * 24000./(24.*3600);
+               u32 units = (u32)(m_time_counter*speed);
+               m_time_counter -= (f32)units / speed;
+               m_time_of_day.set((m_time_of_day.get() + units) % 24000);
+               
+               //dstream<<"Server: m_time_of_day = "<<m_time_of_day.get()<<std::endl;
+
+               /*
+                       Send to clients at constant intervals
+               */
+
+               m_time_of_day_send_timer -= dtime;
+               if(m_time_of_day_send_timer < 0.0)
+               {
+                       m_time_of_day_send_timer = g_settings.getFloat("time_send_interval");
+
+                       //JMutexAutoLock envlock(m_env_mutex);
+                       JMutexAutoLock conlock(m_con_mutex);
+
+                       for(core::map<u16, RemoteClient*>::Iterator
+                               i = m_clients.getIterator();
+                               i.atEnd() == false; i++)
+                       {
+                               RemoteClient *client = i.getNode()->getValue();
+                               //Player *player = m_env.getPlayer(client->peer_id);
+                               
+                               SharedBuffer<u8> data = makePacket_TOCLIENT_TIME_OF_DAY(
+                                               m_time_of_day.get());
+                               // Send as reliable
+                               m_con.Send(client->peer_id, 0, data, true);
+                       }
+               }
+       }
 
        //dstream<<"Server steps "<<dtime<<std::endl;
        
@@ -1434,6 +1478,13 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
 
                // Send inventory to player
                SendInventory(peer->id);
+               
+               // Send time of day
+               {
+                       SharedBuffer<u8> data = makePacket_TOCLIENT_TIME_OF_DAY(
+                                       m_time_of_day.get());
+                       m_con.Send(peer->id, 0, data, true);
+               }
 
                return;
        }
index c20189eb106003f8e703fce2b6e2c92e4a281fab..fddb097d027b16f6608d67d015bbcf58ec0b3376 100644 (file)
@@ -265,9 +265,11 @@ public:
        void GetNextBlocks(Server *server, float dtime,
                        core::array<PrioritySortedBlockTransfer> &dest);
 
-       // Connection and environment should be locked when this is called
-       // steps() objects of blocks not found in active_blocks, then
-       // adds those blocks to active_blocks
+       /*
+               Connection and environment should be locked when this is called.
+               steps() objects of blocks not found in active_blocks, then
+               adds those blocks to active_blocks
+       */
        void SendObjectData(
                        Server *server,
                        float dtime,
@@ -281,14 +283,6 @@ public:
        void SetBlockNotSent(v3s16 p);
        void SetBlocksNotSent(core::map<v3s16, MapBlock*> &blocks);
 
-       //void BlockEmerged();
-
-       /*bool IsSendingBlock(v3s16 p)
-       {
-               JMutexAutoLock lock(m_blocks_sending_mutex);
-               return (m_blocks_sending.find(p) != NULL);
-       }*/
-
        s32 SendingCount()
        {
                JMutexAutoLock lock(m_blocks_sending_mutex);
@@ -457,6 +451,12 @@ private:
        
        // Nodes that are destinations of flowing liquid at the moment
        core::map<v3s16, u8> m_flow_active_nodes;
+
+       // 0-23999
+       MutexedVariable<u32> m_time_of_day;
+       // Used to buffer dtime for adding to m_time_of_day
+       float m_time_counter;
+       float m_time_of_day_send_timer;
        
        friend class EmergeThread;
        friend class RemoteClient;
index e8d7c471d6820a6e2c7b3001fdd0b96df3de0032..5edc8ac7c0794c16c1efea2161936572649448bc 100644 (file)
@@ -86,41 +86,7 @@ IrrlichtDevice *g_device = NULL;
 
 Settings g_settings;
 
-// Sets default settings
-void set_default_settings()
-{
-       // Client stuff
-       g_settings.setDefault("wanted_fps", "30");
-       g_settings.setDefault("fps_max", "60");
-       g_settings.setDefault("viewing_range_nodes_max", "300");
-       g_settings.setDefault("viewing_range_nodes_min", "35");
-       g_settings.setDefault("screenW", "");
-       g_settings.setDefault("screenH", "");
-       g_settings.setDefault("host_game", "");
-       g_settings.setDefault("port", "");
-       g_settings.setDefault("address", "");
-       g_settings.setDefault("name", "");
-       g_settings.setDefault("random_input", "false");
-       g_settings.setDefault("client_delete_unused_sectors_timeout", "1200");
-       g_settings.setDefault("enable_fog", "true");
-
-       // Server stuff
-       g_settings.setDefault("creative_mode", "false");
-       g_settings.setDefault("heightmap_blocksize", "32");
-       g_settings.setDefault("height_randmax", "constant 50.0");
-       g_settings.setDefault("height_randfactor", "constant 0.6");
-       g_settings.setDefault("height_base", "linear 0 0 0");
-       g_settings.setDefault("plants_amount", "1.0");
-       g_settings.setDefault("ravines_amount", "1.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_server_total", "4");
-       g_settings.setDefault("disable_water_climb", "true");
-       g_settings.setDefault("endless_water", "true");
-       g_settings.setDefault("max_block_send_distance", "5");
-       g_settings.setDefault("max_block_generate_distance", "4");
-}
+extern void set_default_settings();
 
 /*
        Debug streams