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);
207 // peer_id=0 means this client has no associated peer
208 // NOTE: If client is made allowed to exist while peer doesn't,
209 // this has to be set to 0 when there is no peer.
210 // Also, the client must be moved to some other container.
212 // The serialization version to use with the client
213 u8 serialization_version;
214 // Version is stored in here after INIT before INIT2
215 u8 pending_serialization_version;
218 m_time_from_building(0.0),
219 m_num_blocks_in_emerge_queue(0)
222 serialization_version = SER_FMT_VER_INVALID;
223 pending_serialization_version = SER_FMT_VER_INVALID;
224 m_nearest_unsent_d = 0;
226 m_blocks_sent_mutex.Init();
227 m_blocks_sending_mutex.Init();
233 // Connection and environment should be locked when this is called
234 void SendBlocks(Server *server, float dtime);
236 // Connection and environment should be locked when this is called
237 // steps() objects of blocks not found in active_blocks, then
238 // adds those blocks to active_blocks
242 core::map<v3s16, bool> &stepped_blocks
245 void GotBlock(v3s16 p);
247 void SentBlock(v3s16 p);
249 void SetBlockNotSent(v3s16 p);
250 void SetBlocksNotSent(core::map<v3s16, MapBlock*> &blocks);
254 // Increments timeouts and removes timed-out blocks from list
255 //void RunSendingTimeouts(float dtime, float timeout);
257 void PrintInfo(std::ostream &o)
259 JMutexAutoLock l2(m_blocks_sent_mutex);
260 JMutexAutoLock l3(m_blocks_sending_mutex);
261 o<<"RemoteClient "<<peer_id<<": "
262 <<"m_num_blocks_in_emerge_queue="
263 <<m_num_blocks_in_emerge_queue.get()
264 <<", m_blocks_sent.size()="<<m_blocks_sent.size()
265 <<", m_blocks_sending.size()="<<m_blocks_sending.size()
266 <<", m_nearest_unsent_d="<<m_nearest_unsent_d
270 // Time from last placing or removing blocks
271 MutexedVariable<float> m_time_from_building;
275 All members that are accessed by many threads should
276 obviously be behind a mutex. The threads include:
277 - main thread (calls step())
278 - server thread (calls AsyncRunStep() and Receive())
282 //TODO: core::map<v3s16, MapBlock*> m_active_blocks
284 // Number of blocks in the emerge queue that have this client as
285 // a receiver. Used for throttling network usage.
286 MutexedVariable<s16> m_num_blocks_in_emerge_queue;
289 Blocks that have been sent to client.
290 - These don't have to be sent again.
291 - A block is cleared from here when client says it has
292 deleted it from it's memory
294 Key is position, value is dummy.
295 No MapBlock* is stored here because the blocks can get deleted.
297 core::map<v3s16, bool> m_blocks_sent;
298 s16 m_nearest_unsent_d;
300 JMutex m_blocks_sent_mutex;
302 Blocks that are currently on the line.
303 This is used for throttling the sending of blocks.
304 - The size of this list is limited to some value
305 Block is added when it is sent with BLOCKDATA.
306 Block is removed when GOTBLOCKS is received.
307 Value is time from sending. (not used at the moment)
309 core::map<v3s16, float> m_blocks_sending;
310 JMutex m_blocks_sending_mutex;
313 class Server : public con::PeerHandler
317 NOTE: Every public method should be thread-safe
320 std::string mapsavedir,
322 MapgenParams mapgen_params
325 void start(unsigned short port);
327 void step(float dtime);
330 void ProcessData(u8 *data, u32 datasize, u16 peer_id);
332 /*void Send(u16 peer_id, u16 channelnum,
333 SharedBuffer<u8> data, bool reliable);*/
335 // Environment and Connection must be locked when called
336 void SendBlockNoLock(u16 peer_id, MapBlock *block, u8 ver);
337 //void SendBlock(u16 peer_id, MapBlock *block, u8 ver);
338 //TODO: Sending of many blocks in a single packet
340 // Environment and Connection must be locked when called
341 //void SendSectorMeta(u16 peer_id, core::list<v2s16> ps, u8 ver);
343 core::list<PlayerInfo> getPlayerInfo();
347 // Virtual methods from con::PeerHandler.
348 // As of now, these create and remove clients and players.
349 // TODO: Make it possible to leave players on server.
350 void peerAdded(con::Peer *peer);
351 void deletingPeer(con::Peer *peer, bool timeout);
353 // Envlock and conlock should be locked when calling these
354 void SendObjectData(float dtime);
355 void SendPlayerInfos();
356 void SendInventory(u16 peer_id);
357 // Sends blocks to clients
358 void SendBlocks(float dtime);
360 // When called, connection mutex should be locked
361 RemoteClient* getClient(u16 peer_id);
363 // NOTE: If connection and environment are both to be locked,
364 // environment shall be locked first.
370 con::Connection m_con;
371 core::map<u16, RemoteClient*> m_clients; // Behind the con mutex
374 JMutex m_step_dtime_mutex;
376 ServerThread m_thread;
377 EmergeThread m_emergethread;
379 BlockEmergeQueue m_emerge_queue;
381 bool m_creative_mode;
383 friend class EmergeThread;
384 friend class RemoteClient;