3 Copyright (C) 2010 celeron55, Perttu Ahola <celeron55@gmail.com>
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License along
16 with this program; if not, write to the Free Software Foundation, Inc.,
17 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 (c) 2010 Perttu Ahola <celeron55@gmail.com>
27 #include "connection.h"
28 #include "environment.h"
29 #include "common_irrlicht.h"
35 #define sleep_ms(x) Sleep(x)
38 #define sleep_ms(x) usleep(x*1000)
41 struct QueuedBlockEmerge
44 // key = peer_id, value = flags
45 core::map<u16, u8> peer_ids;
49 This is a thread-safe class.
51 class BlockEmergeQueue
61 JMutexAutoLock lock(m_mutex);
63 core::list<QueuedBlockEmerge*>::Iterator i;
64 for(i=m_queue.begin(); i!=m_queue.end(); i++)
66 QueuedBlockEmerge *q = *i;
72 peer_id=0 adds with nobody to send to
74 void addBlock(u16 peer_id, v3s16 pos, u8 flags)
76 DSTACK(__FUNCTION_NAME);
78 JMutexAutoLock lock(m_mutex);
83 Find if block is already in queue.
84 If it is, update the peer to it and quit.
86 core::list<QueuedBlockEmerge*>::Iterator i;
87 for(i=m_queue.begin(); i!=m_queue.end(); i++)
89 QueuedBlockEmerge *q = *i;
92 q->peer_ids[peer_id] = flags;
101 QueuedBlockEmerge *q = new QueuedBlockEmerge;
104 q->peer_ids[peer_id] = flags;
105 m_queue.push_back(q);
108 // Returned pointer must be deleted
109 // Returns NULL if queue is empty
110 QueuedBlockEmerge * pop()
112 JMutexAutoLock lock(m_mutex);
114 core::list<QueuedBlockEmerge*>::Iterator i = m_queue.begin();
115 if(i == m_queue.end())
117 QueuedBlockEmerge *q = *i;
124 JMutexAutoLock lock(m_mutex);
125 return m_queue.size();
128 u32 peerItemCount(u16 peer_id)
130 JMutexAutoLock lock(m_mutex);
134 core::list<QueuedBlockEmerge*>::Iterator i;
135 for(i=m_queue.begin(); i!=m_queue.end(); i++)
137 QueuedBlockEmerge *q = *i;
138 if(q->peer_ids.find(peer_id) != NULL)
146 core::list<QueuedBlockEmerge*> m_queue;
152 class ServerThread : public SimpleThread
158 ServerThread(Server *server):
167 class EmergeThread : public SimpleThread
173 EmergeThread(Server *server):
184 if(IsRunning() == false)
194 char name[PLAYERNAME_SIZE];
200 void PrintLine(std::ostream *s);
203 u32 PIChecksum(core::list<PlayerInfo> &l);
206 Used for queueing and sorting block transfers in containers
208 Lower priority number means higher priority.
210 struct PrioritySortedBlockTransfer
212 PrioritySortedBlockTransfer(float a_priority, v3s16 a_pos, u16 a_peer_id)
214 priority = a_priority;
218 bool operator < (PrioritySortedBlockTransfer &other)
220 return priority < other.priority;
230 // peer_id=0 means this client has no associated peer
231 // NOTE: If client is made allowed to exist while peer doesn't,
232 // this has to be set to 0 when there is no peer.
233 // Also, the client must be moved to some other container.
235 // The serialization version to use with the client
236 u8 serialization_version;
237 // Version is stored in here after INIT before INIT2
238 u8 pending_serialization_version;
241 m_time_from_building(9999)
244 serialization_version = SER_FMT_VER_INVALID;
245 pending_serialization_version = SER_FMT_VER_INVALID;
246 m_nearest_unsent_d = 0;
247 m_nearest_unsent_reset_timer = 0.0;
249 m_blocks_sent_mutex.Init();
250 m_blocks_sending_mutex.Init();
253 m_dig_time_remaining = 0;
254 m_dig_tool_item = -1;
261 Finds block that should be sent next to the client.
262 Environment should be locked when this is called.
263 dtime is used for resetting send radius at slow interval
265 void GetNextBlocks(Server *server, float dtime,
266 core::array<PrioritySortedBlockTransfer> &dest);
269 Connection and environment should be locked when this is called.
270 steps() objects of blocks not found in active_blocks, then
271 adds those blocks to active_blocks
276 core::map<v3s16, bool> &stepped_blocks
279 void GotBlock(v3s16 p);
281 void SentBlock(v3s16 p);
283 void SetBlockNotSent(v3s16 p);
284 void SetBlocksNotSent(core::map<v3s16, MapBlock*> &blocks);
288 JMutexAutoLock lock(m_blocks_sending_mutex);
289 return m_blocks_sending.size();
292 // Increments timeouts and removes timed-out blocks from list
293 // NOTE: This doesn't fix the server-not-sending-block bug
294 // because it is related to emerging, not sending.
295 //void RunSendingTimeouts(float dtime, float timeout);
297 void PrintInfo(std::ostream &o)
299 JMutexAutoLock l2(m_blocks_sent_mutex);
300 JMutexAutoLock l3(m_blocks_sending_mutex);
301 o<<"RemoteClient "<<peer_id<<": "
302 <<", m_blocks_sent.size()="<<m_blocks_sent.size()
303 <<", m_blocks_sending.size()="<<m_blocks_sending.size()
304 <<", m_nearest_unsent_d="<<m_nearest_unsent_d
308 // Time from last placing or removing blocks
309 MutexedVariable<float> m_time_from_building;
312 float m_dig_time_remaining;
315 v3s16 m_dig_position;
319 All members that are accessed by many threads should
320 obviously be behind a mutex. The threads include:
321 - main thread (calls step())
322 - server thread (calls AsyncRunStep() and Receive())
326 //TODO: core::map<v3s16, MapBlock*> m_active_blocks
327 //NOTE: Not here, it should be server-wide!
329 // Number of blocks in the emerge queue that have this client as
330 // a receiver. Used for throttling network usage.
331 //MutexedVariable<s16> m_num_blocks_in_emerge_queue;
334 Blocks that have been sent to client.
335 - These don't have to be sent again.
336 - A block is cleared from here when client says it has
337 deleted it from it's memory
339 Key is position, value is dummy.
340 No MapBlock* is stored here because the blocks can get deleted.
342 core::map<v3s16, bool> m_blocks_sent;
343 s16 m_nearest_unsent_d;
345 float m_nearest_unsent_reset_timer;
346 JMutex m_blocks_sent_mutex;
348 Blocks that are currently on the line.
349 This is used for throttling the sending of blocks.
350 - The size of this list is limited to some value
351 Block is added when it is sent with BLOCKDATA.
352 Block is removed when GOTBLOCKS is received.
353 Value is time from sending. (not used at the moment)
355 core::map<v3s16, float> m_blocks_sending;
356 JMutex m_blocks_sending_mutex;
359 /*struct ServerSettings
363 creative_mode = false;
368 class Server : public con::PeerHandler
372 NOTE: Every public method should be thread-safe
375 std::string mapsavedir,
380 void start(unsigned short port);
382 // This is mainly a way to pass the time to the server.
383 // Actual processing is done in an another thread.
384 void step(float dtime);
385 // This is run by ServerThread and does the actual processing
388 void ProcessData(u8 *data, u32 datasize, u16 peer_id);
390 /*void Send(u16 peer_id, u16 channelnum,
391 SharedBuffer<u8> data, bool reliable);*/
393 // Environment and Connection must be locked when called
394 void SendBlockNoLock(u16 peer_id, MapBlock *block, u8 ver);
395 //TODO: Sending of many blocks in a single packet
397 // Environment and Connection must be locked when called
398 //void SendSectorMeta(u16 peer_id, core::list<v2s16> ps, u8 ver);
400 core::list<PlayerInfo> getPlayerInfo();
402 u32 getDayNightRatio()
405 s32 t = (((m_time_of_day.get() + 24000/d/2)%24000)/(24000/d));
406 if(t == d/4 || t == (d-d/4))
408 else if(t < d/4 || t > (d-d/4))
416 // Virtual methods from con::PeerHandler.
417 // As of now, these create and remove clients and players.
418 // TODO: Make it possible to leave players on server.
419 void peerAdded(con::Peer *peer);
420 void deletingPeer(con::Peer *peer, bool timeout);
422 // Envlock and conlock should be locked when calling these
423 void SendObjectData(float dtime);
424 void SendPlayerInfos();
425 void SendInventory(u16 peer_id);
426 // Sends blocks to clients
427 void SendBlocks(float dtime);
429 // When called, connection mutex should be locked
430 RemoteClient* getClient(u16 peer_id);
433 Update water pressure.
434 This also adds suitable nodes to active_nodes.
436 environment has to be locked when calling.
438 void UpdateBlockWaterPressure(MapBlock *block,
439 core::map<v3s16, MapBlock*> &modified_blocks);
441 float m_flowwater_timer;
442 float m_print_info_timer;
443 float m_objectdata_timer;
444 float m_emergethread_trigger_timer;
445 float m_savemap_timer;
447 // NOTE: If connection and environment are both to be locked,
448 // environment shall be locked first.
453 con::Connection m_con;
454 core::map<u16, RemoteClient*> m_clients; // Behind the con mutex
457 JMutex m_step_dtime_mutex;
459 ServerThread m_thread;
460 EmergeThread m_emergethread;
462 BlockEmergeQueue m_emerge_queue;
464 // Nodes that are destinations of flowing liquid at the moment
465 core::map<v3s16, u8> m_flow_active_nodes;
468 MutexedVariable<u32> m_time_of_day;
469 // Used to buffer dtime for adding to m_time_of_day
470 float m_time_counter;
471 float m_time_of_day_send_timer;
473 friend class EmergeThread;
474 friend class RemoteClient;