2 (c) 2010 Perttu Ahola <celeron55@gmail.com>
8 #include "connection.h"
9 #include "environment.h"
10 #include "common_irrlicht.h"
15 #define sleep_ms(x) Sleep(x)
18 #define sleep_ms(x) usleep(x*1000)
21 struct QueuedBlockEmerge
24 // key = peer_id, value = flags
25 core::map<u16, u8> peer_ids;
29 This is a thread-safe class.
31 class BlockEmergeQueue
41 JMutexAutoLock lock(m_mutex);
43 core::list<QueuedBlockEmerge*>::Iterator i;
44 for(i=m_queue.begin(); i!=m_queue.end(); i++)
46 QueuedBlockEmerge *q = *i;
52 peer_id=0 adds with nobody to send to
54 void addBlock(u16 peer_id, v3s16 pos, u8 flags)
56 DSTACK(__FUNCTION_NAME);
58 JMutexAutoLock lock(m_mutex);
63 Find if block is already in queue.
64 If it is, update the peer to it and quit.
66 core::list<QueuedBlockEmerge*>::Iterator i;
67 for(i=m_queue.begin(); i!=m_queue.end(); i++)
69 QueuedBlockEmerge *q = *i;
72 q->peer_ids[peer_id] = flags;
81 QueuedBlockEmerge *q = new QueuedBlockEmerge;
84 q->peer_ids[peer_id] = flags;
88 // Returned pointer must be deleted
89 // Returns NULL if queue is empty
90 QueuedBlockEmerge * pop()
92 JMutexAutoLock lock(m_mutex);
94 core::list<QueuedBlockEmerge*>::Iterator i = m_queue.begin();
95 if(i == m_queue.end())
97 QueuedBlockEmerge *q = *i;
104 JMutexAutoLock lock(m_mutex);
105 return m_queue.size();
108 u32 peerItemCount(u16 peer_id)
110 JMutexAutoLock lock(m_mutex);
114 core::list<QueuedBlockEmerge*>::Iterator i;
115 for(i=m_queue.begin(); i!=m_queue.end(); i++)
117 QueuedBlockEmerge *q = *i;
118 if(q->peer_ids.find(peer_id) != NULL)
126 core::list<QueuedBlockEmerge*> m_queue;
130 class SimpleThread : public JThread
144 virtual ~SimpleThread()
147 virtual void * Thread() = 0;
151 JMutexAutoLock lock(run_mutex);
154 void setRun(bool a_run)
156 JMutexAutoLock lock(run_mutex);
170 class ServerThread : public SimpleThread
176 ServerThread(Server *server):
185 class EmergeThread : public SimpleThread
191 EmergeThread(Server *server):
202 if(IsRunning() == false)
212 char name[PLAYERNAME_SIZE];
218 void PrintLine(std::ostream *s);
221 u32 PIChecksum(core::list<PlayerInfo> &l);
224 Used for queueing and sorting block transfers in containers
226 Lower priority number means higher priority.
228 struct PrioritySortedBlockTransfer
230 PrioritySortedBlockTransfer(float a_priority, v3s16 a_pos, u16 a_peer_id)
232 priority = a_priority;
236 bool operator < (PrioritySortedBlockTransfer &other)
238 return priority < other.priority;
248 // peer_id=0 means this client has no associated peer
249 // NOTE: If client is made allowed to exist while peer doesn't,
250 // this has to be set to 0 when there is no peer.
251 // Also, the client must be moved to some other container.
253 // The serialization version to use with the client
254 u8 serialization_version;
255 // Version is stored in here after INIT before INIT2
256 u8 pending_serialization_version;
259 m_time_from_building(0.0)
260 //m_num_blocks_in_emerge_queue(0)
263 serialization_version = SER_FMT_VER_INVALID;
264 pending_serialization_version = SER_FMT_VER_INVALID;
265 m_nearest_unsent_d = 0;
267 m_blocks_sent_mutex.Init();
268 m_blocks_sending_mutex.Init();
275 Finds block that should be sent next to the client.
276 Environment should be locked when this is called.
277 dtime is used for resetting send radius at slow interval
279 void GetNextBlocks(Server *server, float dtime,
280 core::array<PrioritySortedBlockTransfer> &dest);
282 // Connection and environment should be locked when this is called
283 // steps() objects of blocks not found in active_blocks, then
284 // adds those blocks to active_blocks
288 core::map<v3s16, bool> &stepped_blocks
291 void GotBlock(v3s16 p);
293 void SentBlock(v3s16 p);
295 void SetBlockNotSent(v3s16 p);
296 void SetBlocksNotSent(core::map<v3s16, MapBlock*> &blocks);
298 //void BlockEmerged();
300 /*bool IsSendingBlock(v3s16 p)
302 JMutexAutoLock lock(m_blocks_sending_mutex);
303 return (m_blocks_sending.find(p) != NULL);
308 JMutexAutoLock lock(m_blocks_sending_mutex);
309 return m_blocks_sending.size();
312 // Increments timeouts and removes timed-out blocks from list
313 // NOTE: This doesn't fix the server-not-sending-block bug
314 // because it is related to emerging, not sending.
315 //void RunSendingTimeouts(float dtime, float timeout);
317 void PrintInfo(std::ostream &o)
319 JMutexAutoLock l2(m_blocks_sent_mutex);
320 JMutexAutoLock l3(m_blocks_sending_mutex);
321 o<<"RemoteClient "<<peer_id<<": "
322 /*<<"m_num_blocks_in_emerge_queue="
323 <<m_num_blocks_in_emerge_queue.get()*/
324 <<", m_blocks_sent.size()="<<m_blocks_sent.size()
325 <<", m_blocks_sending.size()="<<m_blocks_sending.size()
326 <<", m_nearest_unsent_d="<<m_nearest_unsent_d
330 // Time from last placing or removing blocks
331 MutexedVariable<float> m_time_from_building;
335 All members that are accessed by many threads should
336 obviously be behind a mutex. The threads include:
337 - main thread (calls step())
338 - server thread (calls AsyncRunStep() and Receive())
342 //TODO: core::map<v3s16, MapBlock*> m_active_blocks
343 //NOTE: Not here, it should be server-wide!
345 // Number of blocks in the emerge queue that have this client as
346 // a receiver. Used for throttling network usage.
347 //MutexedVariable<s16> m_num_blocks_in_emerge_queue;
350 Blocks that have been sent to client.
351 - These don't have to be sent again.
352 - A block is cleared from here when client says it has
353 deleted it from it's memory
355 Key is position, value is dummy.
356 No MapBlock* is stored here because the blocks can get deleted.
358 core::map<v3s16, bool> m_blocks_sent;
359 s16 m_nearest_unsent_d;
361 JMutex m_blocks_sent_mutex;
363 Blocks that are currently on the line.
364 This is used for throttling the sending of blocks.
365 - The size of this list is limited to some value
366 Block is added when it is sent with BLOCKDATA.
367 Block is removed when GOTBLOCKS is received.
368 Value is time from sending. (not used at the moment)
370 core::map<v3s16, float> m_blocks_sending;
371 JMutex m_blocks_sending_mutex;
374 /*struct ServerSettings
378 creative_mode = false;
383 class Server : public con::PeerHandler
387 NOTE: Every public method should be thread-safe
390 std::string mapsavedir,
395 void start(unsigned short port);
397 // This is mainly a way to pass the time to the server.
398 // Actual processing is done in an another thread.
399 void step(float dtime);
400 // This is run by ServerThread and does the actual processing
403 void ProcessData(u8 *data, u32 datasize, u16 peer_id);
405 /*void Send(u16 peer_id, u16 channelnum,
406 SharedBuffer<u8> data, bool reliable);*/
408 // Environment and Connection must be locked when called
409 void SendBlockNoLock(u16 peer_id, MapBlock *block, u8 ver);
410 //TODO: Sending of many blocks in a single packet
412 // Environment and Connection must be locked when called
413 //void SendSectorMeta(u16 peer_id, core::list<v2s16> ps, u8 ver);
415 core::list<PlayerInfo> getPlayerInfo();
419 // Virtual methods from con::PeerHandler.
420 // As of now, these create and remove clients and players.
421 // TODO: Make it possible to leave players on server.
422 void peerAdded(con::Peer *peer);
423 void deletingPeer(con::Peer *peer, bool timeout);
425 // Envlock and conlock should be locked when calling these
426 void SendObjectData(float dtime);
427 void SendPlayerInfos();
428 void SendInventory(u16 peer_id);
429 // Sends blocks to clients
430 void SendBlocks(float dtime);
432 // When called, connection mutex should be locked
433 RemoteClient* getClient(u16 peer_id);
435 // NOTE: If connection and environment are both to be locked,
436 // environment shall be locked first.
442 con::Connection m_con;
443 core::map<u16, RemoteClient*> m_clients; // Behind the con mutex
446 JMutex m_step_dtime_mutex;
448 ServerThread m_thread;
449 EmergeThread m_emergethread;
451 BlockEmergeQueue m_emerge_queue;
453 friend class EmergeThread;
454 friend class RemoteClient;