3 #include <unordered_set>
4 #include <unordered_map>
23 using std::make_unique;
27 using std::unique_ptr;
28 using std::unordered_set;
55 void ServerThread::createDatagrams(vector<LogicNetworkPacket>& safeLogicNetworkPackets, vector<LogicNetworkPacket>& fastLogicNetworkPackets, vector<UDPPacket*>& sendPacketsSafe, vector<UDPPacket*>& sendPacketsFast) {
57 if (safeLogicNetworkPackets.size() > 0) {
58 auto packet = unique_ptr<UDPPacket>(UDPServerClient::createPacket());
60 packet->putBool(
true);
62 for (
auto& logicNetworkPacket: safeLogicNetworkPackets) {
64 char size = logicNetworkPacket.getPosition();
66 auto datagramSize = packet->getPosition();
68 if (datagramSize + 5 + (uint16_t)size > UDPPacket::PACKET_MAX_SIZE) {
70 if (datagramSize < UDPPacket::PACKET_MAX_SIZE) {
74 sendPacketsSafe.push_back(packet.release());
76 packet = unique_ptr<UDPPacket>(UDPServerClient::createPacket());
78 packet->putBool(
true);
81 packet->putByte(size);
83 packet->putInt(logicNetworkPacket.getLogicTypeId());
85 packet->putBytes(logicNetworkPacket.getData(), logicNetworkPacket.getPosition());
88 auto datagramSize = packet->getPosition();
90 if (datagramSize > 17 + 1) {
91 if (datagramSize < UDPPacket::PACKET_MAX_SIZE) {
96 sendPacketsSafe.push_back(packet.release());
100 if (fastLogicNetworkPackets.size() > 0) {
101 auto packet = unique_ptr<UDPPacket>(UDPServerClient::createPacket());
103 packet->putBool(
false);
105 for (
auto& logicNetworkPacket: fastLogicNetworkPackets) {
107 auto size = logicNetworkPacket.getPosition();
109 auto datagramSize = packet->getPosition();
111 if (datagramSize + 5 + (uint16_t)size > UDPPacket::PACKET_MAX_SIZE) {
112 if (datagramSize < UDPPacket::PACKET_MAX_SIZE) {
116 sendPacketsFast.push_back(packet.release());
117 packet = unique_ptr<UDPPacket>(UDPServerClient::createPacket());
119 packet->putBool(
false);
122 packet->putByte(size);
124 packet->putInt(logicNetworkPacket.getLogicTypeId());
126 packet->putBytes(logicNetworkPacket.getData(), logicNetworkPacket.getPosition());
129 auto datagramSize = packet->getPosition();
131 if (datagramSize > 14 + 1) {
132 if (datagramSize < UDPPacket::PACKET_MAX_SIZE - 14) {
137 sendPacketsFast.push_back(packet.release());
143 unordered_set<uint32_t> networkPacketTypesSet;
144 string networkPacketTypes;
145 for (
auto& logicNetworkPacket: logicNetworkPackets) {
146 networkPacketTypesSet.insert(logicNetworkPacket.getLogicTypeId());
148 for (
auto& typeId: networkPacketTypesSet) {
149 if (networkPacketTypes.size() > 0) networkPacketTypes+=
", ";
150 networkPacketTypes+= typeId;
152 return networkPacketTypes;
156 int64_t timeLast = Time::getCurrentMillis();
158 vector<string> newClientKeys;
160 unordered_map<string, vector<LogicNetworkPacket>> clientNetworkPacketsUnhandled;
162 unordered_map<string, vector<LogicNetworkPacket>> mcUpdateSafeLogicNetworkPackets;
163 unordered_map<string, vector<LogicNetworkPacket>> mcUpdateFastLogicNetworkPackets;
165 vector<LogicNetworkPacket> bcUpdateSafeLogicNetworkPackets;
166 vector<LogicNetworkPacket> bcUpdateFastLogicNetworkPackets;
168 unordered_map<string, vector<LogicNetworkPacket>> mcInitialSafeLogicNetworkPackets;
169 unordered_map<string, vector<LogicNetworkPacket>> mcInitialFastLogicNetworkPackets;
171 vector<LogicNetworkPacket> bcInitialSafeLogicNetworkPackets;
172 vector<LogicNetworkPacket> bcInitialFastLogicNetworkPackets;
174 unordered_map<string, vector<LogicNetworkPacket>> clientNetworkPackets;
176 vector<ApplicationServerClient*> clients;
177 vector<ApplicationServerClient*> updateClients;
179 vector<UDPPacket*> bcSendInitialPacketsSafe;
180 vector<UDPPacket*> bcSendInitialPacketsFast;
182 vector<UDPPacket*> mcSendInitialPacketsSafe;
183 vector<UDPPacket*> mcSendInitialPacketsFast;
185 vector<UDPPacket*> bcSendUpdatePacketsSafe;
186 vector<UDPPacket*> bcSendUpdatePacketsFast;
188 vector<UDPPacket*> mcSendUpdatePacketsSafe;
189 vector<UDPPacket*> mcSendUpdatePacketsFast;
191 auto initializedLastFrame =
false;
193 int64_t timeNow = Time::getCurrentMillis();
197 for (
auto& clientKey: clientKeySet) {
199 if (client ==
nullptr)
continue;
201 if (clientKeySetLast.find(clientKey) == clientKeySetLast.end()) {
202 newClientKeys.push_back(client->getKey());
205 updateClients.push_back(client);
208 clients.push_back(client);
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()));
217 packet.setReinjected();
218 clientNetworkPackets[client->getKey()].push_back(packet);
221 clientNetworkPacketsUnhandled.clear();
230 vector<ApplicationServerClient*> newClients;
233 vector<string> newClientKeysToRemove;
234 for (
const auto& clientKey: newClientKeys) {
236 if (client ==
nullptr) {
237 newClientKeysToRemove.push_back(clientKey);
241 newClientKeysToRemove.push_back(clientKey);
242 newClients.push_back(client);
247 for (
const auto& clientKey: newClientKeysToRemove) {
248 newClientKeys.erase(remove(newClientKeys.begin(), newClientKeys.end(), clientKey), newClientKeys.end());
260 for (
auto newLogic: newLogics)
static_cast<NetworkLogic*
>(newLogic)->createInitialNetworkPackets();
264 for (
auto client: clients) {
265 client->getNetworkPacketsMutex().lock();
267 if (
VERBOSE_NETWORK ==
true && clientNetworkPackets[client->getKey()].size() > 0) {
269 "ServerThread::run(): in: " +
270 client->getKey() +
":" +
271 to_string(clientNetworkPackets[client->getKey()].size()) +
": " +
275 client->getNetworkPackets().clear();
276 client->getNetworkPacketsMutex().unlock();
281 for (
auto client: clients) {
282 for (
auto& packet: clientNetworkPackets[client->getKey()]) {
295 while (
true ==
true) {
301 if (addedNewLogics == 0)
break;
304 for (
auto logic: newLogics)
static_cast<NetworkLogic*
>(logic)->createInitialNetworkPackets();
307 for (
auto client: clients) {
308 for (
auto& packet: clientNetworkPackets[client->getKey()]) {
309 for (
auto logic: newLogics) {
322 logic->updateLogic();
323 logic->clearQueuedSounds();
327 while (
true ==
true) {
333 if (addedNewLogics == 0)
break;
336 for (
auto logic: newLogics)
static_cast<NetworkLogic*
>(logic)->createInitialNetworkPackets();
339 for (
auto client: clients) {
340 for (
auto& packet: clientNetworkPackets[client->getKey()]) {
341 for (
auto logic: newLogics) {
351 for (
auto logic: newLogics) {
352 logic->updateLogic();
353 logic->clearQueuedSounds();
361 for (
auto client: clients) {
362 for (
auto& packet: clientNetworkPackets[client->getKey()]) {
363 if (packet.isProcessed() ==
false) {
364 clientNetworkPacketsUnhandled[client->getKey()].push_back(packet);
378 if (logicNetworkPacket.getRecipients().size() == 0) {
379 if (logicNetworkPacket.getSafe() ==
true) {
380 bcUpdateSafeLogicNetworkPackets.push_back(logicNetworkPacket);
382 bcUpdateFastLogicNetworkPackets.push_back(logicNetworkPacket);
386 for (
const auto& recipient: logicNetworkPacket.getRecipients()) {
387 if (logicNetworkPacket.getSafe() ==
true) {
388 mcUpdateSafeLogicNetworkPackets[recipient].push_back(logicNetworkPacket);
390 mcUpdateFastLogicNetworkPackets[recipient].push_back(logicNetworkPacket);
399 if (newClients.size() > 0) {
409 if (logicNetworkPacket.getRecipients().size() == 0) {
410 if (logicNetworkPacket.getSafe() ==
true) {
411 bcInitialSafeLogicNetworkPackets.push_back(logicNetworkPacket);
413 bcInitialFastLogicNetworkPackets.push_back(logicNetworkPacket);
416 for (
auto recipient: logicNetworkPacket.getRecipients()) {
417 if (logicNetworkPacket.getSafe() ==
true) {
418 mcInitialSafeLogicNetworkPackets[recipient].push_back(logicNetworkPacket);
420 mcInitialFastLogicNetworkPackets[recipient].push_back(logicNetworkPacket);
436 if (newClients.size() > 0) {
440 createDatagrams(bcInitialSafeLogicNetworkPackets, bcInitialFastLogicNetworkPackets, bcSendInitialPacketsSafe, bcSendInitialPacketsFast);
443 "ServerThread::run(): initial: bc out: safe: " +
444 to_string(bcSendInitialPacketsSafe.size()) +
": " +
450 "ServerThread::run(): initial: bc out: fast: " +
451 to_string(bcSendInitialPacketsFast.size()) +
": " +
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);
459 for (
auto packet: bcSendInitialPacketsSafe)
delete packet;
460 for (
auto packet: bcSendInitialPacketsFast)
delete packet;
462 bcSendInitialPacketsSafe.clear();
463 bcSendInitialPacketsFast.clear();
467 for (
auto client: newClients) {
468 auto& mcInitialSafePacketsClient = mcInitialSafeLogicNetworkPackets[client->getKey()];
469 auto& mcInitialFastPacketsClient = mcInitialFastLogicNetworkPackets[client->getKey()];
470 createDatagrams(mcInitialSafePacketsClient, mcInitialFastPacketsClient, mcSendInitialPacketsSafe, mcSendInitialPacketsFast);
473 "ServerThread::run(): initial: mc out: " +
475 ": safe: " + to_string(mcSendInitialPacketsSafe.size()) +
": " +
481 "ServerThread::run(): initial: mc out: " +
483 ": fast: " + to_string(mcSendInitialPacketsFast.size()) +
": " +
487 for (
auto packet: mcSendInitialPacketsSafe) client->send(packet,
true);
488 for (
auto packet: mcSendInitialPacketsFast) client->send(packet,
false);
490 mcSendInitialPacketsSafe.clear();
491 mcSendInitialPacketsFast.clear();
501 createDatagrams(bcUpdateSafeLogicNetworkPackets, bcUpdateFastLogicNetworkPackets, bcSendUpdatePacketsSafe, bcSendUpdatePacketsFast);
504 "ServerThread::run(): bc out: safe: " +
505 to_string(bcSendUpdatePacketsSafe.size()) +
": " +
511 "ServerThread::run(): bc out: fast: " +
512 to_string(bcSendUpdatePacketsFast.size()) +
": " +
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);
520 for (
auto packet: bcSendUpdatePacketsSafe)
delete packet;
521 for (
auto packet: bcSendUpdatePacketsFast)
delete packet;
523 bcSendUpdatePacketsSafe.clear();
524 bcSendUpdatePacketsFast.clear();
528 for (
auto client: clients) {
529 auto& mcUpdateSafePacketsClient = mcUpdateSafeLogicNetworkPackets[client->getKey()];
530 auto& mcUpdateFastPacketsClient = mcUpdateFastLogicNetworkPackets[client->getKey()];
533 "ServerThread::run(): mc out: " +
534 client->getKey() +
": safe: " +
535 to_string(mcSendUpdatePacketsSafe.size()) +
": " +
541 "ServerThread::run(): mc out: " +
542 client->getKey() +
": fast: " +
543 ": fast: " + to_string(mcSendUpdatePacketsFast.size()) +
": " +
547 createDatagrams(mcUpdateSafePacketsClient, mcUpdateFastPacketsClient, mcSendUpdatePacketsSafe, mcSendUpdatePacketsFast);
548 for (
auto packet: mcSendUpdatePacketsSafe) client->send(packet,
true);
549 for (
auto packet: mcSendUpdatePacketsFast) client->send(packet,
false);
551 mcSendUpdatePacketsSafe.clear();
552 mcSendUpdatePacketsFast.clear();
558 for (
auto client: clients) {
559 client->releaseReference();
563 clientNetworkPackets.clear();
565 updateClients.clear();
568 mcUpdateSafeLogicNetworkPackets.clear();
569 mcUpdateFastLogicNetworkPackets.clear();
570 bcUpdateSafeLogicNetworkPackets.clear();
571 bcUpdateFastLogicNetworkPackets.clear();
572 mcInitialSafeLogicNetworkPackets.clear();
573 mcInitialFastLogicNetworkPackets.clear();
574 bcInitialSafeLogicNetworkPackets.clear();
575 bcInitialFastLogicNetworkPackets.clear();
578 clientKeySetLast = clientKeySet;
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");
586 if (timeDelta < 16) {
594 timeDelta = Time::getCurrentMillis() - timeLast;
595 if (timeDelta < 16) {
596 Thread::sleep(16 - timeDelta);
598 timeLast = Time::getCurrentMillis();
Application server client.
const vector< Logic * > & getLogics()
virtual void doneUpdateLogics()
Logics finalizations, which is called once per logics updates.
virtual void initUpdateLogics()
Logics initialization, which is called once per logics updates.
int addNewLogics()
Add logics that have been added and tagged as new.
Logic * getLogic(const string &id)
Get logic.
const vector< Logic * > & getNewLogics()
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.
void createDatagrams(vector< LogicNetworkPacket > &safeLogicNetworkPackets, vector< LogicNetworkPacket > &fastLogicNetworkPackets, vector< UDPPacket * > &sendPacketsSafe, vector< UDPPacket * > &sendPacketsFast)
Create datagrams.
static constexpr int32_t VERBOSE_NETWORK
const string getLogicNetworkPacketsLogicTypes(vector< LogicNetworkPacket > &logicNetworkPackets)
Get network packets game logic types.
ApplicationServer * server
virtual void run() override
Abstract run() method, should be implemented by subclassed class, will be called after spawn by start...
Dynamic physics world class.
void update(float deltaTime)
Update world.
CLIENT * getClientByKey(const string &clientKey)
retrieve a client by key, the client reference is acquired, must be released after usage
ClientKeySet getClientKeySet()
get a copy of current client keys
void shutdown()
Shuts down this network client.
void unlock()
Unlocks this mutex.
void lock()
Locks the mutex, additionally mutex locks will block until other locks have been unlocked.
Implementation for read/write lock.
bool isStopRequested()
Returns if stop has been requested.
New client logic interface.
virtual bool handleNewClient(const string &clientId, const string &hostName)=0
Handle new client.