From 4e249fb3fbf75f0359758760d88e22aa5b14533c Mon Sep 17 00:00:00 2001 From: Perttu Ahola Date: Sat, 27 Nov 2010 01:02:21 +0200 Subject: Initial files --- src/server.h | 388 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 388 insertions(+) create mode 100644 src/server.h (limited to 'src/server.h') diff --git a/src/server.h b/src/server.h new file mode 100644 index 000000000..5c856333a --- /dev/null +++ b/src/server.h @@ -0,0 +1,388 @@ +/* +(c) 2010 Perttu Ahola +*/ + +#ifndef SERVER_HEADER +#define SERVER_HEADER + +#include "connection.h" +#include "environment.h" +#include "common_irrlicht.h" +#include + +#ifdef _WIN32 + #include + #define sleep_ms(x) Sleep(x) +#else + #include + #define sleep_ms(x) usleep(x*1000) +#endif + +struct QueuedBlockEmerge +{ + v3s16 pos; + // key = peer_id, value = flags + core::map peer_ids; +}; + +/* + This is a thread-safe class. +*/ +class BlockEmergeQueue +{ +public: + BlockEmergeQueue() + { + m_mutex.Init(); + } + + ~BlockEmergeQueue() + { + JMutexAutoLock lock(m_mutex); + + core::list::Iterator i; + for(i=m_queue.begin(); i!=m_queue.end(); i++) + { + QueuedBlockEmerge *q = *i; + delete q; + } + } + + /* + peer_id=0 adds with nobody to send to + */ + void addBlock(u16 peer_id, v3s16 pos, u8 flags) + { + JMutexAutoLock lock(m_mutex); + + if(peer_id != 0) + { + /* + Find if block is already in queue. + If it is, update the peer to it and quit. + */ + core::list::Iterator i; + for(i=m_queue.begin(); i!=m_queue.end(); i++) + { + QueuedBlockEmerge *q = *i; + if(q->pos == pos) + { + q->peer_ids[peer_id] = flags; + return; + } + } + } + + /* + Add the block + */ + QueuedBlockEmerge *q = new QueuedBlockEmerge; + q->pos = pos; + if(peer_id != 0) + q->peer_ids[peer_id] = flags; + m_queue.push_back(q); + } + + // Returned pointer must be deleted + // Returns NULL if queue is empty + QueuedBlockEmerge * pop() + { + JMutexAutoLock lock(m_mutex); + + core::list::Iterator i = m_queue.begin(); + if(i == m_queue.end()) + return NULL; + QueuedBlockEmerge *q = *i; + m_queue.erase(i); + return q; + } + + u32 size() + { + JMutexAutoLock lock(m_mutex); + return m_queue.size(); + } + +private: + core::list m_queue; + JMutex m_mutex; +}; + +class SimpleThread : public JThread +{ + bool run; + JMutex run_mutex; + +public: + + SimpleThread(): + JThread(), + run(true) + { + run_mutex.Init(); + } + + virtual ~SimpleThread() + {} + + virtual void * Thread() = 0; + + bool getRun() + { + JMutexAutoLock lock(run_mutex); + return run; + } + void setRun(bool a_run) + { + JMutexAutoLock lock(run_mutex); + run = a_run; + } + + void stop() + { + setRun(false); + while(IsRunning()) + sleep_ms(100); + } +}; + +class Server; + +class ServerThread : public SimpleThread +{ + Server *m_server; + +public: + + ServerThread(Server *server): + SimpleThread(), + m_server(server) + { + } + + void * Thread(); +}; + +class EmergeThread : public SimpleThread +{ + Server *m_server; + +public: + + EmergeThread(Server *server): + SimpleThread(), + m_server(server) + { + } + + void * Thread(); + + void trigger() + { + setRun(true); + if(IsRunning() == false) + { + Start(); + } + } +}; + +struct PlayerInfo +{ + u16 id; + char name[PLAYERNAME_SIZE]; + v3f position; + Address address; + float avg_rtt; + + PlayerInfo(); + void PrintLine(std::ostream *s); +}; + +u32 PIChecksum(core::list &l); + +class RemoteClient +{ +public: + // peer_id=0 means this client has no associated peer + // NOTE: If client is made allowed to exist while peer doesn't, + // this has to be set to 0 when there is no peer. + // Also, the client must be moved to some other container. + u16 peer_id; + // The serialization version to use with the client + u8 serialization_version; + // Version is stored in here after INIT before INIT2 + u8 pending_serialization_version; + + RemoteClient(): + m_time_from_building(0.0), + m_num_blocks_in_emerge_queue(0) + { + peer_id = 0; + serialization_version = SER_FMT_VER_INVALID; + pending_serialization_version = SER_FMT_VER_INVALID; + m_nearest_unsent_d = 0; + + m_blocks_sent_mutex.Init(); + m_blocks_sending_mutex.Init(); + } + ~RemoteClient() + { + } + + // Connection and environment should be locked when this is called + void SendBlocks(Server *server, float dtime); + + // Connection and environment should be locked when this is called + // steps() objects of blocks not found in active_blocks, then + // adds those blocks to active_blocks + void SendObjectData( + Server *server, + float dtime, + core::map &stepped_blocks + ); + + void GotBlock(v3s16 p); + + void SentBlock(v3s16 p); + + void SetBlockNotSent(v3s16 p); + void SetBlocksNotSent(core::map &blocks); + + void BlockEmerged(); + + // Increments timeouts and removes timed-out blocks from list + //void RunSendingTimeouts(float dtime, float timeout); + + void PrintInfo(std::ostream &o) + { + JMutexAutoLock l2(m_blocks_sent_mutex); + JMutexAutoLock l3(m_blocks_sending_mutex); + o<<"RemoteClient "<