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"
34 #define sleep_ms(x) Sleep(x)
37 #define sleep_ms(x) usleep(x*1000)
40 struct QueuedBlockEmerge
43 // key = peer_id, value = flags
44 core::map<u16, u8> peer_ids;
48 This is a thread-safe class.
50 class BlockEmergeQueue
60 JMutexAutoLock lock(m_mutex);
62 core::list<QueuedBlockEmerge*>::Iterator i;
63 for(i=m_queue.begin(); i!=m_queue.end(); i++)
65 QueuedBlockEmerge *q = *i;
71 peer_id=0 adds with nobody to send to
73 void addBlock(u16 peer_id, v3s16 pos, u8 flags)
75 DSTACK(__FUNCTION_NAME);
77 JMutexAutoLock lock(m_mutex);
82 Find if block is already in queue.
83 If it is, update the peer to it and quit.
85 core::list<QueuedBlockEmerge*>::Iterator i;
86 for(i=m_queue.begin(); i!=m_queue.end(); i++)
88 QueuedBlockEmerge *q = *i;
91 q->peer_ids[peer_id] = flags;
100 QueuedBlockEmerge *q = new QueuedBlockEmerge;
103 q->peer_ids[peer_id] = flags;
104 m_queue.push_back(q);
107 // Returned pointer must be deleted
108 // Returns NULL if queue is empty
109 QueuedBlockEmerge * pop()
111 JMutexAutoLock lock(m_mutex);
113 core::list<QueuedBlockEmerge*>::Iterator i = m_queue.begin();
114 if(i == m_queue.end())
116 QueuedBlockEmerge *q = *i;
123 JMutexAutoLock lock(m_mutex);
124 return m_queue.size();
127 u32 peerItemCount(u16 peer_id)
129 JMutexAutoLock lock(m_mutex);
133 core::list<QueuedBlockEmerge*>::Iterator i;
134 for(i=m_queue.begin(); i!=m_queue.end(); i++)
136 QueuedBlockEmerge *q = *i;
137 if(q->peer_ids.find(peer_id) != NULL)
145 core::list<QueuedBlockEmerge*> m_queue;
149 class SimpleThread : public JThread
163 virtual ~SimpleThread()
166 virtual void * Thread() = 0;
170 JMutexAutoLock lock(run_mutex);
173 void setRun(bool a_run)
175 JMutexAutoLock lock(run_mutex);
189 class ServerThread : public SimpleThread
195 ServerThread(Server *server):
204 class EmergeThread : public SimpleThread
210 EmergeThread(Server *server):
221 if(IsRunning() == false)
231 char name[PLAYERNAME_SIZE];
237 void PrintLine(std::ostream *s);
240 u32 PIChecksum(core::list<PlayerInfo> &l);
243 Used for queueing and sorting block transfers in containers
245 Lower priority number means higher priority.
247 struct PrioritySortedBlockTransfer
249 PrioritySortedBlockTransfer(float a_priority, v3s16 a_pos, u16 a_peer_id)
251 priority = a_priority;
255 bool operator < (PrioritySortedBlockTransfer &other)
257 return priority < other.priority;
267 // peer_id=0 means this client has no associated peer
268 // NOTE: If client is made allowed to exist while peer doesn't,
269 // this has to be set to 0 when there is no peer.
270 // Also, the client must be moved to some other container.
272 // The serialization version to use with the client
273 u8 serialization_version;
274 // Version is stored in here after INIT before INIT2
275 u8 pending_serialization_version;
278 m_time_from_building(9999)
281 serialization_version = SER_FMT_VER_INVALID;
282 pending_serialization_version = SER_FMT_VER_INVALID;
283 m_nearest_unsent_d = 0;
285 m_blocks_sent_mutex.Init();
286 m_blocks_sending_mutex.Init();
289 m_dig_time_remaining = 0;
290 m_dig_tool_item = -1;
297 Finds block that should be sent next to the client.
298 Environment should be locked when this is called.
299 dtime is used for resetting send radius at slow interval
301 void GetNextBlocks(Server *server, float dtime,
302 core::array<PrioritySortedBlockTransfer> &dest);
304 // Connection and environment should be locked when this is called
305 // steps() objects of blocks not found in active_blocks, then
306 // adds those blocks to active_blocks
310 core::map<v3s16, bool> &stepped_blocks
313 void GotBlock(v3s16 p);
315 void SentBlock(v3s16 p);
317 void SetBlockNotSent(v3s16 p);
318 void SetBlocksNotSent(core::map<v3s16, MapBlock*> &blocks);
320 //void BlockEmerged();
322 /*bool IsSendingBlock(v3s16 p)
324 JMutexAutoLock lock(m_blocks_sending_mutex);
325 return (m_blocks_sending.find(p) != NULL);
330 JMutexAutoLock lock(m_blocks_sending_mutex);
331 return m_blocks_sending.size();
334 // Increments timeouts and removes timed-out blocks from list
335 // NOTE: This doesn't fix the server-not-sending-block bug
336 // because it is related to emerging, not sending.
337 //void RunSendingTimeouts(float dtime, float timeout);
339 void PrintInfo(std::ostream &o)
341 JMutexAutoLock l2(m_blocks_sent_mutex);
342 JMutexAutoLock l3(m_blocks_sending_mutex);
343 o<<"RemoteClient "<<peer_id<<": "
344 <<", m_blocks_sent.size()="<<m_blocks_sent.size()
345 <<", m_blocks_sending.size()="<<m_blocks_sending.size()
346 <<", m_nearest_unsent_d="<<m_nearest_unsent_d
350 // Time from last placing or removing blocks
351 MutexedVariable<float> m_time_from_building;
354 float m_dig_time_remaining;
357 v3s16 m_dig_position;
361 All members that are accessed by many threads should
362 obviously be behind a mutex. The threads include:
363 - main thread (calls step())
364 - server thread (calls AsyncRunStep() and Receive())
368 //TODO: core::map<v3s16, MapBlock*> m_active_blocks
369 //NOTE: Not here, it should be server-wide!
371 // Number of blocks in the emerge queue that have this client as
372 // a receiver. Used for throttling network usage.
373 //MutexedVariable<s16> m_num_blocks_in_emerge_queue;
376 Blocks that have been sent to client.
377 - These don't have to be sent again.
378 - A block is cleared from here when client says it has
379 deleted it from it's memory
381 Key is position, value is dummy.
382 No MapBlock* is stored here because the blocks can get deleted.
384 core::map<v3s16, bool> m_blocks_sent;
385 s16 m_nearest_unsent_d;
387 JMutex m_blocks_sent_mutex;
389 Blocks that are currently on the line.
390 This is used for throttling the sending of blocks.
391 - The size of this list is limited to some value
392 Block is added when it is sent with BLOCKDATA.
393 Block is removed when GOTBLOCKS is received.
394 Value is time from sending. (not used at the moment)
396 core::map<v3s16, float> m_blocks_sending;
397 JMutex m_blocks_sending_mutex;
400 /*struct ServerSettings
404 creative_mode = false;
409 class Server : public con::PeerHandler
413 NOTE: Every public method should be thread-safe
416 std::string mapsavedir,
421 void start(unsigned short port);
423 // This is mainly a way to pass the time to the server.
424 // Actual processing is done in an another thread.
425 void step(float dtime);
426 // This is run by ServerThread and does the actual processing
429 void ProcessData(u8 *data, u32 datasize, u16 peer_id);
431 /*void Send(u16 peer_id, u16 channelnum,
432 SharedBuffer<u8> data, bool reliable);*/
434 // Environment and Connection must be locked when called
435 void SendBlockNoLock(u16 peer_id, MapBlock *block, u8 ver);
436 //TODO: Sending of many blocks in a single packet
438 // Environment and Connection must be locked when called
439 //void SendSectorMeta(u16 peer_id, core::list<v2s16> ps, u8 ver);
441 core::list<PlayerInfo> getPlayerInfo();
445 // Virtual methods from con::PeerHandler.
446 // As of now, these create and remove clients and players.
447 // TODO: Make it possible to leave players on server.
448 void peerAdded(con::Peer *peer);
449 void deletingPeer(con::Peer *peer, bool timeout);
451 // Envlock and conlock should be locked when calling these
452 void SendObjectData(float dtime);
453 void SendPlayerInfos();
454 void SendInventory(u16 peer_id);
455 // Sends blocks to clients
456 void SendBlocks(float dtime);
458 // When called, connection mutex should be locked
459 RemoteClient* getClient(u16 peer_id);
462 Update water pressure.
463 This also adds suitable nodes to active_nodes.
465 environment has to be locked when calling.
467 void UpdateBlockWaterPressure(MapBlock *block,
468 core::map<v3s16, MapBlock*> &modified_blocks);
470 // NOTE: If connection and environment are both to be locked,
471 // environment shall be locked first.
476 con::Connection m_con;
477 core::map<u16, RemoteClient*> m_clients; // Behind the con mutex
480 JMutex m_step_dtime_mutex;
482 ServerThread m_thread;
483 EmergeThread m_emergethread;
485 BlockEmergeQueue m_emerge_queue;
487 // Nodes that are destinations of flowing liquid at the moment
488 core::map<v3s16, u8> m_flow_active_nodes;
490 friend class EmergeThread;
491 friend class RemoteClient;