TDME2  1.9.200
ServerThread.cpp
Go to the documentation of this file.
1 #include <memory>
2 #include <string>
3 #include <unordered_set>
4 #include <unordered_map>
5 #include <vector>
6 
7 #include <tdme/tdme.h>
20 #include <tdme/utilities/Console.h>
21 #include <tdme/utilities/Time.h>
22 
23 using std::make_unique;
24 using std::remove;
25 using std::string;
26 using std::to_string;
27 using std::unique_ptr;
28 using std::unordered_set;
29 using std::vector;
30 
45 
46 ServerThread::ServerThread(Context* context, ApplicationServer* server) : Thread("applicationserverthread"), mutex("applicationserverthread-mutex") {
47  this->context = context;
48  this->server = server;
49 }
50 
52  return &mutex;
53 }
54 
55 void ServerThread::createDatagrams(vector<LogicNetworkPacket>& safeLogicNetworkPackets, vector<LogicNetworkPacket>& fastLogicNetworkPackets, vector<UDPPacket*>& sendPacketsSafe, vector<UDPPacket*>& sendPacketsFast) {
56  // collect safe messages
57  if (safeLogicNetworkPackets.size() > 0) {
58  auto packet = unique_ptr<UDPPacket>(UDPServerClient::createPacket());
59  // safe packet
60  packet->putBool(true);
61  //
62  for (auto& logicNetworkPacket: safeLogicNetworkPackets) {
63  // network packet size
64  char size = logicNetworkPacket.getPosition();
65  // datagram size
66  auto datagramSize = packet->getPosition();
67  //
68  if (datagramSize + 5 + (uint16_t)size > UDPPacket::PACKET_MAX_SIZE) {
69  //
70  if (datagramSize < UDPPacket::PACKET_MAX_SIZE) {
71  // no more network packets
72  packet->putByte(0);
73  }
74  sendPacketsSafe.push_back(packet.release());
75  //
76  packet = unique_ptr<UDPPacket>(UDPServerClient::createPacket());
77  // safe packet
78  packet->putBool(true);
79  }
80  // size
81  packet->putByte(size);
82  // logic type id
83  packet->putInt(logicNetworkPacket.getLogicTypeId());
84  // payload
85  packet->putBytes(logicNetworkPacket.getData(), logicNetworkPacket.getPosition());
86  }
87  // datagram size
88  auto datagramSize = packet->getPosition();
89  //
90  if (datagramSize > 17 + 1) {
91  if (datagramSize < UDPPacket::PACKET_MAX_SIZE) {
92  // end of network packets
93  packet->putByte(0);
94  }
95  //
96  sendPacketsSafe.push_back(packet.release());
97  }
98  }
99  // collect fast messages
100  if (fastLogicNetworkPackets.size() > 0) {
101  auto packet = unique_ptr<UDPPacket>(UDPServerClient::createPacket());
102  // no safe packet
103  packet->putBool(false);
104  //
105  for (auto& logicNetworkPacket: fastLogicNetworkPackets) {
106  // network packet size
107  auto size = logicNetworkPacket.getPosition();
108  // datagram size
109  auto datagramSize = packet->getPosition();
110  //
111  if (datagramSize + 5 + (uint16_t)size > UDPPacket::PACKET_MAX_SIZE) {
112  if (datagramSize < UDPPacket::PACKET_MAX_SIZE) {
113  // no more network packets
114  packet->putByte(0);
115  }
116  sendPacketsFast.push_back(packet.release());
117  packet = unique_ptr<UDPPacket>(UDPServerClient::createPacket());
118  // no safe packet
119  packet->putBool(false);
120  }
121  // size
122  packet->putByte(size);
123  // logic type id
124  packet->putInt(logicNetworkPacket.getLogicTypeId());
125  // payload
126  packet->putBytes(logicNetworkPacket.getData(), logicNetworkPacket.getPosition());
127  }
128  // datagram size
129  auto datagramSize = packet->getPosition();
130  //
131  if (datagramSize > 14 + 1) {
132  if (datagramSize < UDPPacket::PACKET_MAX_SIZE - 14) {
133  // end of network packets
134  packet->putByte(0);
135  }
136  //
137  sendPacketsFast.push_back(packet.release());
138  }
139  }
140 }
141 
142 const string ServerThread::getLogicNetworkPacketsLogicTypes(vector<LogicNetworkPacket>& logicNetworkPackets) {
143  unordered_set<uint32_t> networkPacketTypesSet;
144  string networkPacketTypes;
145  for (auto& logicNetworkPacket: logicNetworkPackets) {
146  networkPacketTypesSet.insert(logicNetworkPacket.getLogicTypeId());
147  }
148  for (auto& typeId: networkPacketTypesSet) {
149  if (networkPacketTypes.size() > 0) networkPacketTypes+= ", ";
150  networkPacketTypes+= typeId;
151  }
152  return networkPacketTypes;
153 }
154 
156  int64_t timeLast = Time::getCurrentMillis();
157  auto clientKeySetLast = server->getClientKeySet();
158  vector<string> newClientKeys;
159  //
160  unordered_map<string, vector<LogicNetworkPacket>> clientNetworkPacketsUnhandled;
161  // multicast packets to send for update
162  unordered_map<string, vector<LogicNetworkPacket>> mcUpdateSafeLogicNetworkPackets;
163  unordered_map<string, vector<LogicNetworkPacket>> mcUpdateFastLogicNetworkPackets;
164  // broadcast packets to send for update
165  vector<LogicNetworkPacket> bcUpdateSafeLogicNetworkPackets;
166  vector<LogicNetworkPacket> bcUpdateFastLogicNetworkPackets;
167  // multicast packets to send for initiation
168  unordered_map<string, vector<LogicNetworkPacket>> mcInitialSafeLogicNetworkPackets;
169  unordered_map<string, vector<LogicNetworkPacket>> mcInitialFastLogicNetworkPackets;
170  // broadcast packets to send for initialization
171  vector<LogicNetworkPacket> bcInitialSafeLogicNetworkPackets;
172  vector<LogicNetworkPacket> bcInitialFastLogicNetworkPackets;
173  //
174  unordered_map<string, vector<LogicNetworkPacket>> clientNetworkPackets;
175  //
176  vector<ApplicationServerClient*> clients;
177  vector<ApplicationServerClient*> updateClients;
178  //
179  vector<UDPPacket*> bcSendInitialPacketsSafe;
180  vector<UDPPacket*> bcSendInitialPacketsFast;
181  //
182  vector<UDPPacket*> mcSendInitialPacketsSafe;
183  vector<UDPPacket*> mcSendInitialPacketsFast;
184  //
185  vector<UDPPacket*> bcSendUpdatePacketsSafe;
186  vector<UDPPacket*> bcSendUpdatePacketsFast;
187  //
188  vector<UDPPacket*> mcSendUpdatePacketsSafe;
189  vector<UDPPacket*> mcSendUpdatePacketsFast;
190  //
191  auto initializedLastFrame = false;
192  while(isStopRequested() == false) {
193  int64_t timeNow = Time::getCurrentMillis();
194 
195  // determine current clients
196  auto clientKeySet = server->getClientKeySet();
197  for (auto& clientKey: clientKeySet) {
198  auto client = static_cast<ApplicationServerClient*>(server->getClientByKey(clientKey));
199  if (client == nullptr) continue;
200  // new client?
201  if (clientKeySetLast.find(clientKey) == clientKeySetLast.end()) {
202  newClientKeys.push_back(client->getKey());
203  } else {
204  // nope, known client
205  updateClients.push_back(client);
206  }
207  // we have a client
208  clients.push_back(client);
209  }
210 
211  // push unhandlet packets to client packets, display an warning if not handled for 1s
212  for (auto client: clients) {
213  for (auto& packet: clientNetworkPacketsUnhandled[client->getKey()]) {
214  if (timeNow - packet.getTime() > 1000L) {
215  Console::println("ServerThread::run(): unhandled IN packet: 1s late: " + client->getKey() + ": " + to_string(packet.getLogicTypeId()));
216  }
217  packet.setReinjected();
218  clientNetworkPackets[client->getKey()].push_back(packet);
219  }
220  }
221  clientNetworkPacketsUnhandled.clear();
222 
223  // logic + handle network packets
224  mutex.lock();
225 
226  //
228 
229  // new clients
230  vector<ApplicationServerClient*> newClients;
231  {
232  // new clients
233  vector<string> newClientKeysToRemove;
234  for (const auto& clientKey: newClientKeys) {
235  auto client = static_cast<ApplicationServerClient*>(server->getClientByKey(clientKey));
236  if (client == nullptr) {
237  newClientKeysToRemove.push_back(clientKey);
238  continue;
239  }
240  if (dynamic_cast<NewClientLogic*>(context->getLogic("l"))->handleNewClient(clientKey, client->getIp() + ":" + to_string(client->getPort())) == true) {
241  newClientKeysToRemove.push_back(clientKey);
242  newClients.push_back(client);
243  } else {
244  client->shutdown();
245  }
246  }
247  for (const auto& clientKey: newClientKeysToRemove) {
248  newClientKeys.erase(remove(newClientKeys.begin(), newClientKeys.end(), clientKey), newClientKeys.end());
249  }
250  }
251 
252  {
253  // new logics: create initial network packets for clients
254  auto newLogics = context->getNewLogics();
255 
256  // basically add new logics to logics
258 
259  //
260  for (auto newLogic: newLogics) static_cast<NetworkLogic*>(newLogic)->createInitialNetworkPackets();
261  }
262 
263  // fetch client packets
264  for (auto client: clients) {
265  client->getNetworkPacketsMutex().lock();
266  clientNetworkPackets[client->getKey()] = client->getNetworkPackets();
267  if (VERBOSE_NETWORK == true && clientNetworkPackets[client->getKey()].size() > 0) {
268  Console::println(
269  "ServerThread::run(): in: " +
270  client->getKey() + ":" +
271  to_string(clientNetworkPackets[client->getKey()].size()) + ": " +
272  "(" + getLogicNetworkPacketsLogicTypes(client->getNetworkPackets()) + ")"
273  );
274  }
275  client->getNetworkPackets().clear();
276  client->getNetworkPacketsMutex().unlock();
277  }
278 
279  // handle client packets
280  // TODO: do rather a hashmap for looking up logics by packet type id
281  for (auto client: clients) {
282  for (auto& packet: clientNetworkPackets[client->getKey()]) {
283  for (auto logic: context->getLogics()) {
284  NetworkLogic* networkLogic = static_cast<NetworkLogic*>(logic);
285  if (networkLogic->getNetworkPacketTypeId() == packet.getLogicTypeId()) {
286  packet.reset();
287  networkLogic->handleNetworkPacket(packet);
288  }
289  }
290  }
291  }
292 
293  // we propably have logics added, create initial packets from them and handle their in packets
294  // TODO: do rather a hashmap for looking up logics by packet type id
295  while (true == true) {
296  // new logics: create initial network packets for clients
297  auto newLogics = context->getNewLogics();
298 
299  // basically add new logics to logics
300  auto addedNewLogics = context->addNewLogics();
301  if (addedNewLogics == 0) break;
302 
303  //
304  for (auto logic: newLogics) static_cast<NetworkLogic*>(logic)->createInitialNetworkPackets();
305 
306  // handle client packets
307  for (auto client: clients) {
308  for (auto& packet: clientNetworkPackets[client->getKey()]) {
309  for (auto logic: newLogics) {
310  NetworkLogic* networkLogic = static_cast<NetworkLogic*>(logic);
311  if (networkLogic->getNetworkPacketTypeId() == packet.getLogicTypeId()) {
312  packet.reset();
313  networkLogic->handleNetworkPacket(packet);
314  }
315  }
316  }
317  }
318  }
319 
320  // do logics
321  for (auto logic: context->getLogics()) {
322  logic->updateLogic();
323  logic->clearQueuedSounds();
324  }
325 
326  // we propably have logics added, create initial packets from them and handle their in packets
327  while (true == true) {
328  // new logics: create initial network packets for clients
329  auto newLogics = context->getNewLogics();
330 
331  // basically add new logics to logics
332  auto addedNewLogics = context->addNewLogics();
333  if (addedNewLogics == 0) break;
334 
335  //
336  for (auto logic: newLogics) static_cast<NetworkLogic*>(logic)->createInitialNetworkPackets();
337 
338  // handle client packets
339  for (auto client: clients) {
340  for (auto& packet: clientNetworkPackets[client->getKey()]) {
341  for (auto logic: newLogics) {
342  NetworkLogic* networkLogic = static_cast<NetworkLogic*>(logic);
343  if (networkLogic->getNetworkPacketTypeId() == packet.getLogicTypeId()) {
344  packet.reset();
345  networkLogic->handleNetworkPacket(packet);
346  }
347  }
348  }
349  }
350 
351  for (auto logic: newLogics) {
352  logic->updateLogic();
353  logic->clearQueuedSounds();
354  }
355  }
356 
357  // fire on logics processed
358  for (auto logic: context->getLogics()) logic->onLogicsProcessed();
359 
360  // check if there are in packets that have not yet been processed
361  for (auto client: clients) {
362  for (auto& packet: clientNetworkPackets[client->getKey()]) {
363  if (packet.isProcessed() == false) {
364  clientNetworkPacketsUnhandled[client->getKey()].push_back(packet);
365  }
366  }
367  }
368 
369  // colllect broadcast network packets for update
370  for (auto logic: context->getLogics()) {
371  NetworkLogic* networkLogic = static_cast<NetworkLogic*>(logic);
372  for (auto& logicNetworkPacket: networkLogic->getNetworkPackets()) {
373  // packet logic type id
374  if (logicNetworkPacket.getLogicTypeId() == LogicNetworkPacket::LOGIC_TYPEID_NONE) {
375  logicNetworkPacket.setLogicTypeId(networkLogic->getNetworkPacketTypeId());
376  }
377  // broadcast
378  if (logicNetworkPacket.getRecipients().size() == 0) {
379  if (logicNetworkPacket.getSafe() == true) {
380  bcUpdateSafeLogicNetworkPackets.push_back(logicNetworkPacket);
381  } else {
382  bcUpdateFastLogicNetworkPackets.push_back(logicNetworkPacket);
383  }
384  } else {
385  // multicast
386  for (const auto& recipient: logicNetworkPacket.getRecipients()) {
387  if (logicNetworkPacket.getSafe() == true) {
388  mcUpdateSafeLogicNetworkPackets[recipient].push_back(logicNetworkPacket);
389  } else {
390  mcUpdateFastLogicNetworkPackets[recipient].push_back(logicNetworkPacket);
391  }
392  }
393  }
394  }
395  networkLogic->getNetworkPackets().clear();
396  }
397 
398  // colllect broadcast network packets for initialization
399  if (newClients.size() > 0) {
400  for (auto logic: context->getLogics()) {
401  NetworkLogic* networkLogic = static_cast<NetworkLogic*>(logic);
402  networkLogic->createInitialNetworkPackets();
403  for (auto& logicNetworkPacket: networkLogic->getNetworkPackets()) {
404  // set logic type id
405  if (logicNetworkPacket.getLogicTypeId() == LogicNetworkPacket::LOGIC_TYPEID_NONE) {
406  logicNetworkPacket.setLogicTypeId(networkLogic->getNetworkPacketTypeId());
407  }
408  // broadcast packets
409  if (logicNetworkPacket.getRecipients().size() == 0) {
410  if (logicNetworkPacket.getSafe() == true) {
411  bcInitialSafeLogicNetworkPackets.push_back(logicNetworkPacket);
412  } else {
413  bcInitialFastLogicNetworkPackets.push_back(logicNetworkPacket);
414  }
415  } else {
416  for (auto recipient: logicNetworkPacket.getRecipients()) {
417  if (logicNetworkPacket.getSafe() == true) {
418  mcInitialSafeLogicNetworkPackets[recipient].push_back(logicNetworkPacket);
419  } else {
420  mcInitialFastLogicNetworkPackets[recipient].push_back(logicNetworkPacket);
421  }
422  }
423  }
424  }
425  networkLogic->getNetworkPackets().clear();
426  }
427  }
428 
429  //
431 
432  // done
433  mutex.unlock();
434 
435  // send initial messages to new clients
436  if (newClients.size() > 0) {
437  // broad cast
438  {
439  // broadcast datagrams to send for initialization
440  createDatagrams(bcInitialSafeLogicNetworkPackets, bcInitialFastLogicNetworkPackets, bcSendInitialPacketsSafe, bcSendInitialPacketsFast);
441  if (VERBOSE_NETWORK == true && bcSendInitialPacketsSafe.size() > 0) {
442  Console::println(
443  "ServerThread::run(): initial: bc out: safe: " +
444  to_string(bcSendInitialPacketsSafe.size()) + ": " +
445  getLogicNetworkPacketsLogicTypes(bcInitialSafeLogicNetworkPackets)
446  );
447  }
448  if (VERBOSE_NETWORK == true && bcSendInitialPacketsFast.size() > 0) {
449  Console::println(
450  "ServerThread::run(): initial: bc out: fast: " +
451  to_string(bcSendInitialPacketsFast.size()) + ": " +
452  getLogicNetworkPacketsLogicTypes(bcInitialFastLogicNetworkPackets)
453  );
454  }
455  for (auto client: newClients) {
456  for (auto packet: bcSendInitialPacketsSafe) client->send(packet, true, false);
457  for (auto packet: bcSendInitialPacketsFast) client->send(packet, false, false);
458  }
459  for (auto packet: bcSendInitialPacketsSafe) delete packet;
460  for (auto packet: bcSendInitialPacketsFast) delete packet;
461  //
462  bcSendInitialPacketsSafe.clear();
463  bcSendInitialPacketsFast.clear();
464  }
465  {
466  // multi cast
467  for (auto client: newClients) {
468  auto& mcInitialSafePacketsClient = mcInitialSafeLogicNetworkPackets[client->getKey()];
469  auto& mcInitialFastPacketsClient = mcInitialFastLogicNetworkPackets[client->getKey()];
470  createDatagrams(mcInitialSafePacketsClient, mcInitialFastPacketsClient, mcSendInitialPacketsSafe, mcSendInitialPacketsFast);
471  if (VERBOSE_NETWORK == true && mcSendInitialPacketsSafe.size() > 0) {
472  Console::println(
473  "ServerThread::run(): initial: mc out: " +
474  client->getKey() +
475  ": safe: " + to_string(mcSendInitialPacketsSafe.size()) + ": " +
476  getLogicNetworkPacketsLogicTypes(mcInitialSafePacketsClient)
477  );
478  }
479  if (VERBOSE_NETWORK == true && mcSendInitialPacketsFast.size() > 0) {
480  Console::println(
481  "ServerThread::run(): initial: mc out: " +
482  client->getKey() +
483  ": fast: " + to_string(mcSendInitialPacketsFast.size()) + ": " +
484  getLogicNetworkPacketsLogicTypes(mcInitialFastPacketsClient)
485  );
486  }
487  for (auto packet: mcSendInitialPacketsSafe) client->send(packet, true);
488  for (auto packet: mcSendInitialPacketsFast) client->send(packet, false);
489  //
490  mcSendInitialPacketsSafe.clear();
491  mcSendInitialPacketsFast.clear();
492  }
493  }
494  }
495 
496  // send messages to update clients
497  {
498  // broad cast
499  {
500  // broadcast datagrams to send for update
501  createDatagrams(bcUpdateSafeLogicNetworkPackets, bcUpdateFastLogicNetworkPackets, bcSendUpdatePacketsSafe, bcSendUpdatePacketsFast);
502  if (VERBOSE_NETWORK == true && bcSendUpdatePacketsSafe.size() > 0) {
503  Console::println(
504  "ServerThread::run(): bc out: safe: " +
505  to_string(bcSendUpdatePacketsSafe.size()) + ": " +
506  getLogicNetworkPacketsLogicTypes(bcUpdateSafeLogicNetworkPackets)
507  );
508  }
509  if (VERBOSE_NETWORK == true && bcSendUpdatePacketsFast.size() > 0) {
510  Console::println(
511  "ServerThread::run(): bc out: fast: " +
512  to_string(bcSendUpdatePacketsFast.size()) + ": " +
513  getLogicNetworkPacketsLogicTypes(bcUpdateFastLogicNetworkPackets)
514  );
515  }
516  for (auto client: updateClients) {
517  for (auto packet: bcSendUpdatePacketsSafe) client->send(packet, true, false);
518  for (auto packet: bcSendUpdatePacketsFast) client->send(packet, false, false);
519  }
520  for (auto packet: bcSendUpdatePacketsSafe) delete packet;
521  for (auto packet: bcSendUpdatePacketsFast) delete packet;
522  //
523  bcSendUpdatePacketsSafe.clear();
524  bcSendUpdatePacketsFast.clear();
525  }
526  // multi cast
527  {
528  for (auto client: clients) {
529  auto& mcUpdateSafePacketsClient = mcUpdateSafeLogicNetworkPackets[client->getKey()];
530  auto& mcUpdateFastPacketsClient = mcUpdateFastLogicNetworkPackets[client->getKey()];
531  if (VERBOSE_NETWORK == true && mcSendUpdatePacketsSafe.size() > 0) {
532  Console::println(
533  "ServerThread::run(): mc out: " +
534  client->getKey() + ": safe: " +
535  to_string(mcSendUpdatePacketsSafe.size()) + ": " +
536  getLogicNetworkPacketsLogicTypes(mcUpdateSafePacketsClient)
537  );
538  }
539  if (VERBOSE_NETWORK == true && mcSendUpdatePacketsFast.size() > 0) {
540  Console::println(
541  "ServerThread::run(): mc out: " +
542  client->getKey() + ": fast: " +
543  ": fast: " + to_string(mcSendUpdatePacketsFast.size()) + ": " +
544  getLogicNetworkPacketsLogicTypes(mcUpdateFastPacketsClient)
545  );
546  }
547  createDatagrams(mcUpdateSafePacketsClient, mcUpdateFastPacketsClient, mcSendUpdatePacketsSafe, mcSendUpdatePacketsFast);
548  for (auto packet: mcSendUpdatePacketsSafe) client->send(packet, true);
549  for (auto packet: mcSendUpdatePacketsFast) client->send(packet, false);
550  //
551  mcSendUpdatePacketsSafe.clear();
552  mcSendUpdatePacketsFast.clear();
553  }
554  }
555  }
556 
557  // release references
558  for (auto client: clients) {
559  client->releaseReference();
560  }
561 
562  //
563  clientNetworkPackets.clear();
564  clients.clear();
565  updateClients.clear();
566 
567  //
568  mcUpdateSafeLogicNetworkPackets.clear();
569  mcUpdateFastLogicNetworkPackets.clear();
570  bcUpdateSafeLogicNetworkPackets.clear();
571  bcUpdateFastLogicNetworkPackets.clear();
572  mcInitialSafeLogicNetworkPackets.clear();
573  mcInitialFastLogicNetworkPackets.clear();
574  bcInitialSafeLogicNetworkPackets.clear();
575  bcInitialFastLogicNetworkPackets.clear();
576 
577  // set last client key set
578  clientKeySetLast = clientKeySet;
579 
580  // get some rest
581  int64_t timeDelta = Time::getCurrentMillis() - timeLast;
582  if (timeDelta > 33) {
583  Console::println("ServerThread::run(): time delta < 33FPS, it took " + to_string(timeDelta) + " ms to compute");
584  timeDelta = 33;
585  } else
586  if (timeDelta < 16) {
587  timeDelta = 16;
588  }
589  // update world if we have any
590  if (context->isInitialized() == true) {
591  context->getWorld()->update(timeDelta / 1000.0f);
592  } else {
593  }
594  timeDelta = Time::getCurrentMillis() - timeLast;
595  if (timeDelta < 16) {
596  Thread::sleep(16 - timeDelta);
597  }
598  timeLast = Time::getCurrentMillis();
599  }
600 }
const vector< Logic * > & getLogics()
Definition: Context.h:584
virtual void doneUpdateLogics()
Logics finalizations, which is called once per logics updates.
Definition: Context.cpp:719
virtual void initUpdateLogics()
Logics initialization, which is called once per logics updates.
Definition: Context.cpp:716
int addNewLogics()
Add logics that have been added and tagged as new.
Definition: Context.h:569
Logic * getLogic(const string &id)
Get logic.
Definition: Context.h:560
const vector< Logic * > & getNewLogics()
Definition: Context.h:591
static constexpr uint32_t LOGIC_TYPEID_NONE
vector< LogicNetworkPacket > & getNetworkPackets()
Get outgoing network packets.
virtual void createInitialNetworkPackets()=0
Send network packet for initialization Note: This is server only for now.
virtual uint32_t getNetworkPacketTypeId()=0
virtual void handleNetworkPacket(LogicNetworkPacket &packet)=0
Handle network packet.
Application server thread.
Definition: ServerThread.h:25
void createDatagrams(vector< LogicNetworkPacket > &safeLogicNetworkPackets, vector< LogicNetworkPacket > &fastLogicNetworkPackets, vector< UDPPacket * > &sendPacketsSafe, vector< UDPPacket * > &sendPacketsFast)
Create datagrams.
static constexpr int32_t VERBOSE_NETWORK
Definition: ServerThread.h:43
const string getLogicNetworkPacketsLogicTypes(vector< LogicNetworkPacket > &logicNetworkPackets)
Get network packets game logic types.
virtual void run() override
Abstract run() method, should be implemented by subclassed class, will be called after spawn by start...
Dynamic physics world class.
Definition: World.h:38
void update(float deltaTime)
Update world.
Definition: World.cpp:251
CLIENT * getClientByKey(const string &clientKey)
retrieve a client by key, the client reference is acquired, must be released after usage
Definition: Server.h:109
ClientKeySet getClientKeySet()
get a copy of current client keys
Definition: Server.h:94
void shutdown()
Shuts down this network client.
Mutex implementation.
Definition: Mutex.h:19
void unlock()
Unlocks this mutex.
Definition: Mutex.h:54
void lock()
Locks the mutex, additionally mutex locks will block until other locks have been unlocked.
Definition: Mutex.h:47
Implementation for read/write lock.
Definition: ReadWriteLock.h:17
Base class for threads.
Definition: Thread.h:20
bool isStopRequested()
Returns if stop has been requested.
Definition: Thread.h:77
Console class.
Definition: Console.h:29
Time utility class.
Definition: Time.h:20
New client logic interface.
virtual bool handleNewClient(const string &clientId, const string &hostName)=0
Handle new client.