The server-side heartbeat is working and stable
This commit is contained in:
@@ -81,6 +81,7 @@ private:
|
|||||||
|
|
||||||
//utility methods
|
//utility methods
|
||||||
//TODO: a function that only sends to characters in a certain proximity
|
//TODO: a function that only sends to characters in a certain proximity
|
||||||
|
void CleanupLostConnection(int index);
|
||||||
void PumpPacket(SerialPacket* const);
|
void PumpPacket(SerialPacket* const);
|
||||||
void PumpCharacterUnload(int uid);
|
void PumpCharacterUnload(int uid);
|
||||||
void CopyCharacterToPacket(CharacterPacket* const packet, int characterIndex);
|
void CopyCharacterToPacket(CharacterPacket* const packet, int characterIndex);
|
||||||
|
|||||||
@@ -26,6 +26,7 @@
|
|||||||
#include "utility.hpp"
|
#include "utility.hpp"
|
||||||
|
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
#include <chrono>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
@@ -144,6 +145,24 @@ void ServerApplication::Proc() {
|
|||||||
//update the internals
|
//update the internals
|
||||||
//BUG: #30 Update the internals i.e. player positions
|
//BUG: #30 Update the internals i.e. player positions
|
||||||
|
|
||||||
|
//TODO: This could be checked only every few seconds
|
||||||
|
//Check connections
|
||||||
|
for (auto& it : clientMap) {
|
||||||
|
if (std::chrono::steady_clock::now() - it.second.GetLastBeat() > std::chrono::seconds(5)) {
|
||||||
|
ServerPacket newPacket;
|
||||||
|
newPacket.type = SerialPacketType::PING;
|
||||||
|
network.SendTo(it.second.GetAddress(), &newPacket);
|
||||||
|
it.second.IncrementAttempts();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (it.second.GetAttempts() > 2) {
|
||||||
|
CleanupLostConnection(it.first);
|
||||||
|
|
||||||
|
//all iterators are invalid, so we can't continue
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//give the computer a break
|
//give the computer a break
|
||||||
SDL_Delay(10);
|
SDL_Delay(10);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,7 +34,17 @@ void ServerApplication::HandlePing(ServerPacket* const argPacket) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ServerApplication::HandlePong(ServerPacket* const argPacket) {
|
void ServerApplication::HandlePong(ServerPacket* const argPacket) {
|
||||||
//TODO: ServerApplications::HandlePong()
|
//find and update the specified client
|
||||||
|
|
||||||
|
//BUGFIX: running multiple clients on one computer will result in matching host values; check the ports too
|
||||||
|
for (auto& it : clientMap) {
|
||||||
|
if (it.second.GetAddress().host == argPacket->srcAddress.host &&
|
||||||
|
it.second.GetAddress().port == argPacket->srcAddress.port
|
||||||
|
) {
|
||||||
|
it.second.ResetAttempts();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ServerApplication::HandleBroadcastRequest(ServerPacket* const argPacket) {
|
void ServerApplication::HandleBroadcastRequest(ServerPacket* const argPacket) {
|
||||||
@@ -172,6 +182,8 @@ void ServerApplication::HandleCharacterNew(CharacterPacket* const argPacket) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//TODO: Make sure that a character's owner's account is loaded before continuing
|
||||||
|
|
||||||
//send this new character to all clients
|
//send this new character to all clients
|
||||||
CharacterPacket newPacket;
|
CharacterPacket newPacket;
|
||||||
newPacket.type = SerialPacketType::CHARACTER_NEW;
|
newPacket.type = SerialPacketType::CHARACTER_NEW;
|
||||||
@@ -257,6 +269,47 @@ void ServerApplication::HandleSynchronize(ClientPacket* const argPacket) {
|
|||||||
//utility methods
|
//utility methods
|
||||||
//-------------------------
|
//-------------------------
|
||||||
|
|
||||||
|
void ServerApplication::CleanupLostConnection(int clientIndex) {
|
||||||
|
//NOTE: This assumes each player has only one account and character at a time
|
||||||
|
|
||||||
|
//find the account
|
||||||
|
int accountIndex = -1;
|
||||||
|
for (auto& it : *accountMgr.GetContainer()) {
|
||||||
|
if (it.second.GetClientIndex() == clientIndex) {
|
||||||
|
accountIndex = it.first;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//find the character
|
||||||
|
int characterIndex = -1;
|
||||||
|
for (auto& it : *characterMgr.GetContainer()) {
|
||||||
|
if (it.second.GetOwner() == accountIndex) {
|
||||||
|
characterIndex = it.first;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//send a dissconnection message just in case
|
||||||
|
ClientPacket newPacket;
|
||||||
|
newPacket.type = SerialPacketType::DISCONNECT;
|
||||||
|
network.SendTo(clientMap[clientIndex].GetAddress(), &newPacket);
|
||||||
|
|
||||||
|
//clean up this mess
|
||||||
|
characterMgr.UnloadCharacter(characterIndex);
|
||||||
|
accountMgr.UnloadAccount(accountIndex);
|
||||||
|
clientMap.erase(clientIndex);
|
||||||
|
|
||||||
|
PumpCharacterUnload(characterIndex);
|
||||||
|
|
||||||
|
//output a message
|
||||||
|
std::cerr << "Connection lost: " << std::endl;
|
||||||
|
std::cerr << "\tClient: " << clientIndex << std::endl;
|
||||||
|
std::cerr << "\tAccount: " << accountIndex << std::endl;
|
||||||
|
std::cerr << "\tCharacter: " << characterIndex << std::endl;
|
||||||
|
std::cout << clientMap.size() << " clients and " << accountMgr.GetContainer()->size() << " accounts total" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
//TODO: a function that only sends to characters in a certain proximity
|
//TODO: a function that only sends to characters in a certain proximity
|
||||||
|
|
||||||
void ServerApplication::PumpPacket(SerialPacket* const argPacket) {
|
void ServerApplication::PumpPacket(SerialPacket* const argPacket) {
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
TODO: Heartbeat systems
|
|
||||||
TODO: Rejection messages
|
TODO: Rejection messages
|
||||||
TODO: The error handling is terrible
|
TODO: The error handling is terrible
|
||||||
TODO: Move the statistics into their own SQL table, instead of duplicating the structure a dozen times
|
TODO: Move the statistics into their own SQL table, instead of duplicating the structure a dozen times
|
||||||
|
|||||||
Reference in New Issue
Block a user