added heartbeat support

This commit is contained in:
CPunch 2020-08-18 20:34:39 -05:00
parent b2325eb308
commit 24d30a05bf
10 changed files with 57 additions and 10 deletions

View File

@ -5,7 +5,7 @@ CC = clang++ # using GNU C++ compiler
WIN_CC = x86_64-w64-mingw32-g++ # using GNU C++ compiler WIN_CC = x86_64-w64-mingw32-g++ # using GNU C++ compiler
# -w suppresses all warnings (the part that's commented out helps me find memory leaks, it ruins performance though!) # -w suppresses all warnings (the part that's commented out helps me find memory leaks, it ruins performance though!)
COMPILER_FLAGS = -std=c++17 -o3 -static #-g3 -fsanitize=address COMPILER_FLAGS = -std=c++17 -o3 -g3 -fsanitize=address
WIN_COMPILER_FLAGS = -std=c++17 -o3 -static #-g3 -fsanitize=address WIN_COMPILER_FLAGS = -std=c++17 -o3 -static #-g3 -fsanitize=address
#LINKER_FLAGS specifies the libraries we're linking against (NONE, this is a single header library.) #LINKER_FLAGS specifies the libraries we're linking against (NONE, this is a single header library.)

View File

@ -1,4 +1,5 @@
#include "CNProtocol.hpp" #include "CNProtocol.hpp"
#include "CNStructs.hpp"
// ========================================================[[ CNSocketEncryption ]]======================================================== // ========================================================[[ CNSocketEncryption ]]========================================================
@ -228,8 +229,12 @@ void CNServer::init() {
} }
} }
CNServer::CNServer() {}; CNServer::CNServer() {
CNServer::CNServer(uint16_t p): port(p) {} lastTimer = getTime();
};
CNServer::CNServer(uint16_t p): port(p) {
lastTimer = getTime();
}
void CNServer::start() { void CNServer::start() {
std::cout << "Starting server at *:" << port << std::endl; std::cout << "Starting server at *:" << port << std::endl;
@ -274,6 +279,11 @@ void CNServer::start() {
} }
} }
if (getTime() - lastTimer > 2000) { // every 2 seconds call the onTimer method
onTimer();
lastTimer = getTime();
}
#ifdef _WIN32 #ifdef _WIN32
Sleep(0); Sleep(0);
#else #else
@ -302,4 +312,5 @@ void CNServer::kill() {
connections.clear(); connections.clear();
} }
void CNServer::killConnection(CNSocket* cns) {} // stubbed lol void CNServer::killConnection(CNSocket* cns) {} // stubbed lol
void CNServer::onTimer() {} // stubbed lol

View File

@ -124,6 +124,7 @@ public:
class CNServer { class CNServer {
protected: protected:
std::list<CNSocket*> connections; std::list<CNSocket*> connections;
std::mutex activeCrit;
SOCKET sock; SOCKET sock;
uint16_t port; uint16_t port;
@ -132,7 +133,7 @@ protected:
void init(); void init();
bool active = true; bool active = true;
std::mutex activeCrit; long int lastTimer;
public: public:
PacketHandler pHandler; PacketHandler pHandler;
@ -143,6 +144,7 @@ public:
void start(); void start();
void kill(); void kill();
virtual void killConnection(CNSocket* cns); virtual void killConnection(CNSocket* cns);
virtual void onTimer(); // called every 2 seconds
}; };
#endif #endif

View File

@ -29,4 +29,21 @@ void CNShardServer::killConnection(CNSocket* cns) {
PlayerManager::removePlayer(cns); PlayerManager::removePlayer(cns);
CNSharedData::erasePlayer(cachedPlr.SerialKey); CNSharedData::erasePlayer(cachedPlr.SerialKey);
}
void CNShardServer::onTimer() {
long int currTime = getTime();
auto cachedPlayers = PlayerManager::players;
for (auto pair : cachedPlayers) {
if (pair.second.lastHeartbeat != 0 && currTime - pair.second.lastHeartbeat > 4000) { // if the client hadn't responded in 4 seconds, its a dead connection so throw it out
pair.first->kill();
continue;
}
// passed the heartbeat, send another
sP_FE2CL_REQ_LIVE_CHECK* data = (sP_FE2CL_REQ_LIVE_CHECK*)xmalloc(sizeof(sP_FE2CL_REQ_LIVE_CHECK));
pair.first->sendPacket(new CNPacketData((void*)data, P_FE2CL_REQ_LIVE_CHECK, sizeof(sP_FE2CL_REQ_LIVE_CHECK), pair.first->getFEKey()));
}
} }

View File

@ -9,6 +9,7 @@ enum SHARDPACKETID {
// client 2 shard // client 2 shard
P_CL2FE_REQ_PC_ENTER = 318767105, P_CL2FE_REQ_PC_ENTER = 318767105,
P_CL2FE_REQ_PC_LOADING_COMPLETE = 318767245, P_CL2FE_REQ_PC_LOADING_COMPLETE = 318767245,
P_CL2FE_REP_LIVE_CHECK = 318767221,
P_CL2FE_REQ_PC_MOVE = 318767107, P_CL2FE_REQ_PC_MOVE = 318767107,
P_CL2FE_REQ_PC_STOP = 318767108, P_CL2FE_REQ_PC_STOP = 318767108,
P_CL2FE_REQ_PC_JUMP = 318767109, P_CL2FE_REQ_PC_JUMP = 318767109,
@ -21,6 +22,7 @@ enum SHARDPACKETID {
// shard 2 client // shard 2 client
P_FE2CL_REP_PC_ENTER_SUCC = 822083586, P_FE2CL_REP_PC_ENTER_SUCC = 822083586,
P_FE2CL_REP_PC_LOADING_COMPLETE_SUCC = 822083833, P_FE2CL_REP_PC_LOADING_COMPLETE_SUCC = 822083833,
P_FE2CL_REQ_LIVE_CHECK = 822083792,
P_FE2CL_PC_NEW = 822083587, P_FE2CL_PC_NEW = 822083587,
P_FE2CL_PC_MOVE = 822083592, P_FE2CL_PC_MOVE = 822083592,
P_FE2CL_PC_STOP = 822083593, P_FE2CL_PC_STOP = 822083593,
@ -44,6 +46,7 @@ public:
CNShardServer(uint16_t p); CNShardServer(uint16_t p);
void killConnection(CNSocket* cns); void killConnection(CNSocket* cns);
void onTimer();
}; };
#endif #endif

View File

@ -336,11 +336,14 @@ struct sP_CL2FE_REQ_PC_ENTER {
int64_t iEnterSerialKey; int64_t iEnterSerialKey;
}; };
struct sP_CL2FE_REQ_PC_LOADING_COMPLETE { struct sP_CL2FE_REQ_PC_LOADING_COMPLETE {
int32_t iPC_ID; int32_t iPC_ID;
}; };
struct sP_CL2FE_REP_LIVE_CHECK {
int32_t iTempValue;
};
struct sP_CL2FE_REQ_PC_MOVE { struct sP_CL2FE_REQ_PC_MOVE {
uint64_t iCliTime; uint64_t iCliTime;
int32_t iX; int32_t iX;
@ -429,6 +432,10 @@ struct sP_FE2CL_REP_PC_LOADING_COMPLETE_SUCC {
int32_t iPC_ID; int32_t iPC_ID;
}; };
struct sP_FE2CL_REQ_LIVE_CHECK {
int32_t iTempValue;
};
// literally just a wrapper for a sPCAppearanceData struct :/ // literally just a wrapper for a sPCAppearanceData struct :/
struct sP_FE2CL_PC_NEW { struct sP_FE2CL_PC_NEW {
sPCAppearanceData PCAppearanceData; sPCAppearanceData PCAppearanceData;

View File

@ -21,12 +21,14 @@ void PlayerManager::init() {
REGISTER_SHARD_PACKET(P_CL2FE_REQ_PC_MOVEPLATFORM, PlayerManager::movePlatformPlayer); REGISTER_SHARD_PACKET(P_CL2FE_REQ_PC_MOVEPLATFORM, PlayerManager::movePlatformPlayer);
REGISTER_SHARD_PACKET(P_CL2FE_REQ_PC_GOTO, PlayerManager::gotoPlayer); REGISTER_SHARD_PACKET(P_CL2FE_REQ_PC_GOTO, PlayerManager::gotoPlayer);
REGISTER_SHARD_PACKET(P_CL2FE_GM_REQ_PC_SET_VALUE, PlayerManager::setSpecialPlayer); REGISTER_SHARD_PACKET(P_CL2FE_GM_REQ_PC_SET_VALUE, PlayerManager::setSpecialPlayer);
REGISTER_SHARD_PACKET(P_CL2FE_REP_LIVE_CHECK, PlayerManager::heartbeatPlayer);
} }
void PlayerManager::addPlayer(CNSocket* key, Player plr) { void PlayerManager::addPlayer(CNSocket* key, Player plr) {
players[key] = PlayerView(); players[key] = PlayerView();
players[key].viewable = std::list<CNSocket*>(); players[key].viewable = std::list<CNSocket*>();
players[key].plr = plr; players[key].plr = plr;
players[key].lastHeartbeat = 0;
std::cout << U16toU8(plr.PCStyle.szFirstName) << U16toU8(plr.PCStyle.szLastName) << " has joined!" << std::endl; std::cout << U16toU8(plr.PCStyle.szFirstName) << U16toU8(plr.PCStyle.szLastName) << " has joined!" << std::endl;
std::cout << players.size() << " players" << std::endl; std::cout << players.size() << " players" << std::endl;
@ -384,4 +386,8 @@ void PlayerManager::setSpecialPlayer(CNSocket* sock, CNPacketData* data) {
response->iSetValueType = setData->iSetValueType; response->iSetValueType = setData->iSetValueType;
sock->sendPacket(new CNPacketData((void*)response, P_FE2CL_GM_REP_PC_SET_VALUE, sizeof(sP_FE2CL_GM_REP_PC_SET_VALUE), sock->getFEKey())); sock->sendPacket(new CNPacketData((void*)response, P_FE2CL_GM_REP_PC_SET_VALUE, sizeof(sP_FE2CL_GM_REP_PC_SET_VALUE), sock->getFEKey()));
}
void PlayerManager::heartbeatPlayer(CNSocket* sock, CNPacketData* data) {
players[sock].lastHeartbeat = getTime();
} }

View File

@ -12,6 +12,7 @@
struct PlayerView { struct PlayerView {
std::list<CNSocket*> viewable; std::list<CNSocket*> viewable;
Player plr; Player plr;
int long lastHeartbeat;
}; };
@ -33,7 +34,7 @@ namespace PlayerManager {
void movePlatformPlayer(CNSocket* sock, CNPacketData* data); void movePlatformPlayer(CNSocket* sock, CNPacketData* data);
void gotoPlayer(CNSocket* sock, CNPacketData* data); void gotoPlayer(CNSocket* sock, CNPacketData* data);
void setSpecialPlayer(CNSocket* sock, CNPacketData* data); void setSpecialPlayer(CNSocket* sock, CNPacketData* data);
void heartbeatPlayer(CNSocket* sock, CNPacketData* data);
} }
#endif #endif

View File

@ -30,8 +30,8 @@ int main() {
ChatManager::init(); ChatManager::init();
std::cout << "[INFO] Starting Server Threads..." << std::endl; std::cout << "[INFO] Starting Server Threads..." << std::endl;
CNShardServer loginServer(settings::LOGINPORT); CNLoginServer loginServer(settings::LOGINPORT);
CNLoginServer shardServer(settings::SHARDPORT); CNShardServer shardServer(settings::SHARDPORT);
std::thread shardThread(startShard, (CNShardServer*)&shardServer); std::thread shardThread(startShard, (CNShardServer*)&shardServer);

View File

@ -8,7 +8,7 @@ bool settings::LOGINRANDCHARACTERS = false;
int settings::SHARDPORT = 8002; int settings::SHARDPORT = 8002;
std::string settings::SHARDSERVERIP = "127.0.0.1"; std::string settings::SHARDSERVERIP = "127.0.0.1";
int settings::VIEWDISTANCE = 25000; int settings::VIEWDISTANCE = 20000;
// default spawn point is city hall // default spawn point is city hall
int settings::SPAWN_X = 179213; int settings::SPAWN_X = 179213;