3 Copyright (C) 2010-2014 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 Lesser General Public License as published by
7 the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser 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.
19 #ifndef _CLIENTIFACE_H_
20 #define _CLIENTIFACE_H_
22 #include "irr_v3d.h" // for irrlicht datatypes
24 #include "constants.h"
25 #include "serialization.h" // for SER_FMT_VER_INVALID
26 #include "jthread/jmutex.h"
34 class ServerEnvironment;
64 Used for queueing and sorting block transfers in containers
66 Lower priority number means higher priority.
68 struct PrioritySortedBlockTransfer
70 PrioritySortedBlockTransfer(float a_priority, v3s16 a_pos, u16 a_peer_id)
72 priority = a_priority;
76 bool operator < (const PrioritySortedBlockTransfer &other) const
78 return priority < other.priority;
88 // peer_id=0 means this client has no associated peer
89 // NOTE: If client is made allowed to exist while peer doesn't,
90 // this has to be set to 0 when there is no peer.
91 // Also, the client must be moved to some other container.
93 // The serialization version to use with the client
94 u8 serialization_version;
96 u16 net_proto_version;
99 peer_id(PEER_ID_INEXISTENT),
100 serialization_version(SER_FMT_VER_INVALID),
101 net_proto_version(0),
102 m_time_from_building(9999),
103 m_pending_serialization_version(SER_FMT_VER_INVALID),
105 m_nearest_unsent_d(0),
106 m_nearest_unsent_reset_timer(0.0),
107 m_excess_gotblocks(0),
108 m_nothing_to_send_counter(0),
109 m_nothing_to_send_pause_timer(0.0),
118 Finds block that should be sent next to the client.
119 Environment should be locked when this is called.
120 dtime is used for resetting send radius at slow interval
122 void GetNextBlocks(ServerEnvironment *env, EmergeManager* emerge,
123 float dtime, std::vector<PrioritySortedBlockTransfer> &dest);
125 void GotBlock(v3s16 p);
127 void SentBlock(v3s16 p);
129 void SetBlockNotSent(v3s16 p);
130 void SetBlocksNotSent(std::map<v3s16, MapBlock*> &blocks);
134 return m_blocks_sending.size();
137 // Increments timeouts and removes timed-out blocks from list
138 // NOTE: This doesn't fix the server-not-sending-block bug
139 // because it is related to emerging, not sending.
140 //void RunSendingTimeouts(float dtime, float timeout);
142 void PrintInfo(std::ostream &o)
144 o<<"RemoteClient "<<peer_id<<": "
145 <<"m_blocks_sent.size()="<<m_blocks_sent.size()
146 <<", m_blocks_sending.size()="<<m_blocks_sending.size()
147 <<", m_nearest_unsent_d="<<m_nearest_unsent_d
148 <<", m_excess_gotblocks="<<m_excess_gotblocks
150 m_excess_gotblocks = 0;
153 // Time from last placing or removing blocks
154 float m_time_from_building;
157 List of active objects that the client knows of.
160 std::set<u16> m_known_objects;
162 ClientState getState()
165 std::string getName()
168 void setName(std::string name)
171 /* update internal client state */
172 void notifyEvent(ClientStateEvent event);
174 /* set expected serialization version */
175 void setPendingSerializationVersion(u8 version)
176 { m_pending_serialization_version = version; }
178 void confirmSerializationVersion()
179 { serialization_version = m_pending_serialization_version; }
182 // Version is stored in here after INIT before INIT2
183 u8 m_pending_serialization_version;
185 /* current state of client */
189 Blocks that have been sent to client.
190 - These don't have to be sent again.
191 - A block is cleared from here when client says it has
192 deleted it from it's memory
194 Key is position, value is dummy.
195 No MapBlock* is stored here because the blocks can get deleted.
197 std::set<v3s16> m_blocks_sent;
198 s16 m_nearest_unsent_d;
200 float m_nearest_unsent_reset_timer;
203 Blocks that are currently on the line.
204 This is used for throttling the sending of blocks.
205 - The size of this list is limited to some value
206 Block is added when it is sent with BLOCKDATA.
207 Block is removed when GOTBLOCKS is received.
208 Value is time from sending. (not used at the moment)
210 std::map<v3s16, float> m_blocks_sending;
213 Count of excess GotBlocks().
214 There is an excess amount because the client sometimes
215 gets a block so late that the server sends it again,
216 and the client then sends two GOTBLOCKs.
217 This is resetted by PrintInfo()
219 u32 m_excess_gotblocks;
221 // CPU usage optimization
222 u32 m_nothing_to_send_counter;
223 float m_nothing_to_send_pause_timer;
227 class ClientInterface {
232 ClientInterface(con::Connection* con);
236 void step(float dtime);
238 /* get list of active client id's */
239 std::list<u16> getClientIDs(ClientState min_state=Active);
241 /* get list of client player names */
242 std::vector<std::string> getPlayerNames();
244 /* send message to client */
245 void send(u16 peer_id, u8 channelnum, SharedBuffer<u8> data, bool reliable);
247 /* send to all clients */
248 void sendToAll(u16 channelnum, SharedBuffer<u8> data, bool reliable);
250 /* delete a client */
251 void DeleteClient(u16 peer_id);
254 void CreateClient(u16 peer_id);
256 /* get a client by peer_id */
257 RemoteClient* getClientNoEx(u16 peer_id, ClientState state_min=Active);
259 /* get client by peer_id (make sure you have list lock before!*/
260 RemoteClient* lockedGetClientNoEx(u16 peer_id, ClientState state_min=Active);
262 /* get state of client by id*/
263 ClientState getClientState(u16 peer_id);
265 /* set client playername */
266 void setPlayerName(u16 peer_id,std::string name);
268 /* get protocol version of client */
269 u16 getProtocolVersion(u16 peer_id);
271 /* event to update client state */
272 void event(u16 peer_id, ClientStateEvent event);
274 /* set environment */
275 void setEnv(ServerEnvironment* env)
276 { assert(m_env == 0); m_env = env; }
279 //TODO find way to avoid this functions
281 { m_clients_mutex.Lock(); }
283 { m_clients_mutex.Unlock(); }
285 std::map<u16, RemoteClient*>& getClientList()
286 { return m_clients; }
289 /* update internal player list */
290 void UpdatePlayerList();
293 con::Connection* m_con;
294 JMutex m_clients_mutex;
295 // Connected clients (behind the con mutex)
296 std::map<u16, RemoteClient*> m_clients;
297 std::vector<std::string> m_clients_names; //for announcing masterserver
300 ServerEnvironment *m_env;
303 float m_print_info_timer;