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 JMutexAutoLock lock(m_mutex);
61 Find if block is already in queue.
62 If it is, update the peer to it and quit.
64 core::list<QueuedBlockEmerge*>::Iterator i;
65 for(i=m_queue.begin(); i!=m_queue.end(); i++)
67 QueuedBlockEmerge *q = *i;
70 q->peer_ids[peer_id] = flags;
79 QueuedBlockEmerge *q = new QueuedBlockEmerge;
82 q->peer_ids[peer_id] = flags;
86 // Returned pointer must be deleted
87 // Returns NULL if queue is empty
88 QueuedBlockEmerge * pop()
90 JMutexAutoLock lock(m_mutex);
92 core::list<QueuedBlockEmerge*>::Iterator i = m_queue.begin();
93 if(i == m_queue.end())
95 QueuedBlockEmerge *q = *i;
102 JMutexAutoLock lock(m_mutex);
103 return m_queue.size();
107 core::list<QueuedBlockEmerge*> m_queue;
111 class SimpleThread : public JThread
125 virtual ~SimpleThread()
128 virtual void * Thread() = 0;
132 JMutexAutoLock lock(run_mutex);
135 void setRun(bool a_run)
137 JMutexAutoLock lock(run_mutex);
151 class ServerThread : public SimpleThread
157 ServerThread(Server *server):
166 class EmergeThread : public SimpleThread
172 EmergeThread(Server *server):
183 if(IsRunning() == false)
193 char name[PLAYERNAME_SIZE];
199 void PrintLine(std::ostream *s);
202 u32 PIChecksum(core::list<PlayerInfo> &l);
205 Used for queueing and sorting block transfers in containers
207 Lower priority number means higher priority.
209 struct PrioritySortedBlockTransfer
211 PrioritySortedBlockTransfer(float a_priority, v3s16 a_pos, u16 a_dest_peer)
213 priority = a_priority;
215 dest_peer = a_dest_peer;
217 bool operator < (PrioritySortedBlockTransfer &other)
219 return priority < other.priority;
229 // peer_id=0 means this client has no associated peer
230 // NOTE: If client is made allowed to exist while peer doesn't,
231 // this has to be set to 0 when there is no peer.
232 // Also, the client must be moved to some other container.
234 // The serialization version to use with the client
235 u8 serialization_version;
236 // Version is stored in here after INIT before INIT2
237 u8 pending_serialization_version;
240 m_time_from_building(0.0),
241 m_num_blocks_in_emerge_queue(0)
244 serialization_version = SER_FMT_VER_INVALID;
245 pending_serialization_version = SER_FMT_VER_INVALID;
246 m_nearest_unsent_d = 0;
248 m_blocks_sent_mutex.Init();
249 m_blocks_sending_mutex.Init();
255 // Connection and environment should be locked when this is called
256 void SendBlocks(Server *server, float dtime);
258 // Connection and environment should be locked when this is called
259 // steps() objects of blocks not found in active_blocks, then
260 // adds those blocks to active_blocks
264 core::map<v3s16, bool> &stepped_blocks
267 void GotBlock(v3s16 p);
269 void SentBlock(v3s16 p);
271 void SetBlockNotSent(v3s16 p);
272 void SetBlocksNotSent(core::map<v3s16, MapBlock*> &blocks);
276 // Increments timeouts and removes timed-out blocks from list
277 // NOTE: This doesn't fix the server-not-sending-block bug
278 // because it is related to emerging, not sending.
279 //void RunSendingTimeouts(float dtime, float timeout);
281 void PrintInfo(std::ostream &o)
283 JMutexAutoLock l2(m_blocks_sent_mutex);
284 JMutexAutoLock l3(m_blocks_sending_mutex);
285 o<<"RemoteClient "<<peer_id<<": "
286 <<"m_num_blocks_in_emerge_queue="
287 <<m_num_blocks_in_emerge_queue.get()
288 <<", m_blocks_sent.size()="<<m_blocks_sent.size()
289 <<", m_blocks_sending.size()="<<m_blocks_sending.size()
290 <<", m_nearest_unsent_d="<<m_nearest_unsent_d
294 // Time from last placing or removing blocks
295 MutexedVariable<float> m_time_from_building;
299 All members that are accessed by many threads should
300 obviously be behind a mutex. The threads include:
301 - main thread (calls step())
302 - server thread (calls AsyncRunStep() and Receive())
306 //TODO: core::map<v3s16, MapBlock*> m_active_blocks
308 // Number of blocks in the emerge queue that have this client as
309 // a receiver. Used for throttling network usage.
310 MutexedVariable<s16> m_num_blocks_in_emerge_queue;
313 Blocks that have been sent to client.
314 - These don't have to be sent again.
315 - A block is cleared from here when client says it has
316 deleted it from it's memory
318 Key is position, value is dummy.
319 No MapBlock* is stored here because the blocks can get deleted.
321 core::map<v3s16, bool> m_blocks_sent;
322 s16 m_nearest_unsent_d;
324 JMutex m_blocks_sent_mutex;
326 Blocks that are currently on the line.
327 This is used for throttling the sending of blocks.
328 - The size of this list is limited to some value
329 Block is added when it is sent with BLOCKDATA.
330 Block is removed when GOTBLOCKS is received.
331 Value is time from sending. (not used at the moment)
333 core::map<v3s16, float> m_blocks_sending;
334 JMutex m_blocks_sending_mutex;
337 /*struct ServerSettings
341 creative_mode = false;
346 class Server : public con::PeerHandler
350 NOTE: Every public method should be thread-safe
353 std::string mapsavedir,
356 MapParams map_params,
357 float objectdata_inverval,
358 u16 active_object_range
361 void start(unsigned short port);
363 void step(float dtime);
366 void ProcessData(u8 *data, u32 datasize, u16 peer_id);
368 /*void Send(u16 peer_id, u16 channelnum,
369 SharedBuffer<u8> data, bool reliable);*/
371 // Environment and Connection must be locked when called
372 void SendBlockNoLock(u16 peer_id, MapBlock *block, u8 ver);
373 //void SendBlock(u16 peer_id, MapBlock *block, u8 ver);
374 //TODO: Sending of many blocks in a single packet
376 // Environment and Connection must be locked when called
377 //void SendSectorMeta(u16 peer_id, core::list<v2s16> ps, u8 ver);
379 core::list<PlayerInfo> getPlayerInfo();
383 // Virtual methods from con::PeerHandler.
384 // As of now, these create and remove clients and players.
385 // TODO: Make it possible to leave players on server.
386 void peerAdded(con::Peer *peer);
387 void deletingPeer(con::Peer *peer, bool timeout);
389 // Envlock and conlock should be locked when calling these
390 void SendObjectData(float dtime);
391 void SendPlayerInfos();
392 void SendInventory(u16 peer_id);
393 // Sends blocks to clients
394 void SendBlocks(float dtime);
396 // When called, connection mutex should be locked
397 RemoteClient* getClient(u16 peer_id);
399 // NOTE: If connection and environment are both to be locked,
400 // environment shall be locked first.
406 con::Connection m_con;
407 core::map<u16, RemoteClient*> m_clients; // Behind the con mutex
410 JMutex m_step_dtime_mutex;
412 ServerThread m_thread;
413 EmergeThread m_emergethread;
415 BlockEmergeQueue m_emerge_queue;
418 bool m_creative_mode;
419 float m_objectdata_interval;
420 u16 m_active_object_range;
422 friend class EmergeThread;
423 friend class RemoteClient;