Only send live checks when the connection has been silent for a while.

Also:
* Made the timeout configurable
* Removed the stale randomcharacters config option
* Switched to time_t for time values, even though it doesn't really
matter that much
* Halved the keepAliveTimer frequency
This commit is contained in:
dongresource 2020-09-16 17:45:53 +02:00
parent 501d153894
commit f7571607ba
7 changed files with 25 additions and 20 deletions

View File

@ -9,9 +9,6 @@ verbosity=1
[login] [login]
# must be kept in sync with loginInfo.php # must be kept in sync with loginInfo.php
port=8001 port=8001
# enables two randomly generated characters in the
# character selection menu for convenience
randomcharacters=true
# will all custom names be approved instantly? # will all custom names be approved instantly?
acceptallcustomnames=true acceptallcustomnames=true
# how often should everything be flushed to the database? # how often should everything be flushed to the database?
@ -25,6 +22,9 @@ ip=127.0.0.1
# distance at which other players and NPCs become visible # distance at which other players and NPCs become visible
playerdistance=20000 playerdistance=20000
npcdistance=16000 npcdistance=16000
# time, in milliseconds, to wait before kicking a non-responsive client
# default is 1 minute
timeout=60000
# little message players see when they enter the game # little message players see when they enter the game
motd=Welcome to OpenFusion! motd=Welcome to OpenFusion!
# NPC json data # NPC json data

View File

@ -172,15 +172,15 @@ public:
}; };
class CNServer; class CNServer;
typedef void (*TimerHandler)(CNServer* serv, uint64_t time); typedef void (*TimerHandler)(CNServer* serv, time_t time);
// timer struct // timer struct
struct TimerEvent { struct TimerEvent {
TimerHandler handlr; TimerHandler handlr;
uint64_t delta; // time to be added to the current time on reset time_t delta; // time to be added to the current time on reset
uint64_t scheduledEvent; // time to call handlr() time_t scheduledEvent; // time to call handlr()
TimerEvent(TimerHandler h, uint64_t d): handlr(h), delta(d) { TimerEvent(TimerHandler h, time_t d): handlr(h), delta(d) {
scheduledEvent = 0; scheduledEvent = 0;
} }
}; };

View File

@ -16,7 +16,7 @@ std::list<TimerEvent> CNShardServer::Timers;
CNShardServer::CNShardServer(uint16_t p) { CNShardServer::CNShardServer(uint16_t p) {
port = p; port = p;
pHandler = &CNShardServer::handlePacket; pHandler = &CNShardServer::handlePacket;
REGISTER_SHARD_TIMER(keepAliveTimer, 2000); REGISTER_SHARD_TIMER(keepAliveTimer, 4000);
REGISTER_SHARD_TIMER(periodicSaveTimer, settings::DBSAVEINTERVAL*1000); REGISTER_SHARD_TIMER(periodicSaveTimer, settings::DBSAVEINTERVAL*1000);
init(); init();
} }
@ -28,24 +28,26 @@ void CNShardServer::handlePacket(CNSocket* sock, CNPacketData* data) {
ShardPackets[data->type](sock, data); ShardPackets[data->type](sock, data);
else if (settings::VERBOSITY > 0) else if (settings::VERBOSITY > 0)
std::cerr << "OpenFusion: SHARD UNIMPLM ERR. PacketType: " << Defines::p2str(CL2FE, data->type) << " (" << data->type << ")" << std::endl; std::cerr << "OpenFusion: SHARD UNIMPLM ERR. PacketType: " << Defines::p2str(CL2FE, data->type) << " (" << data->type << ")" << std::endl;
PlayerManager::players[sock].lastHeartbeat = getTime();
} }
void CNShardServer::keepAliveTimer(CNServer* serv, uint64_t currTime) { void CNShardServer::keepAliveTimer(CNServer* serv, time_t currTime) {
auto cachedPlayers = PlayerManager::players; auto cachedPlayers = PlayerManager::players;
for (auto& pair : cachedPlayers) { for (auto& pair : cachedPlayers) {
if (pair.second.lastHeartbeat != 0 && currTime - pair.second.lastHeartbeat > 60000) { // if the client hadn't responded in 60 seconds, its a dead connection so throw it out if (pair.second.lastHeartbeat != 0 && currTime - pair.second.lastHeartbeat > settings::TIMEOUT) {
// if the client hasn't responded in 60 seconds, its a dead connection so throw it out
pair.first->kill(); pair.first->kill();
continue; } else if (pair.second.lastHeartbeat != 0 && currTime - pair.second.lastHeartbeat > settings::TIMEOUT/2) {
} // if the player hasn't responded in 30 seconds, send a live check
// passed the heartbeat, send another
INITSTRUCT(sP_FE2CL_REQ_LIVE_CHECK, data); INITSTRUCT(sP_FE2CL_REQ_LIVE_CHECK, data);
pair.first->sendPacket((void*)&data, P_FE2CL_REQ_LIVE_CHECK, sizeof(sP_FE2CL_REQ_LIVE_CHECK)); pair.first->sendPacket((void*)&data, P_FE2CL_REQ_LIVE_CHECK, sizeof(sP_FE2CL_REQ_LIVE_CHECK));
} }
} }
}
void CNShardServer::periodicSaveTimer(CNServer* serv, uint64_t currTime) { void CNShardServer::periodicSaveTimer(CNServer* serv, time_t currTime) {
auto cachedPlayers = PlayerManager::players; auto cachedPlayers = PlayerManager::players;
for (auto& pair : cachedPlayers) { for (auto& pair : cachedPlayers) {
@ -73,7 +75,7 @@ void CNShardServer::killConnection(CNSocket* cns) {
} }
void CNShardServer::onStep() { void CNShardServer::onStep() {
uint64_t currTime = getTime(); time_t currTime = getTime();
for (TimerEvent& event : Timers) { for (TimerEvent& event : Timers) {
if (event.scheduledEvent == 0) { if (event.scheduledEvent == 0) {

View File

@ -12,8 +12,8 @@ class CNShardServer : public CNServer {
private: private:
static void handlePacket(CNSocket* sock, CNPacketData* data); static void handlePacket(CNSocket* sock, CNPacketData* data);
static void keepAliveTimer(CNServer*, uint64_t); static void keepAliveTimer(CNServer*, time_t);
static void periodicSaveTimer(CNServer* serv, uint64_t currTime); static void periodicSaveTimer(CNServer* serv, time_t currTime);
public: public:
static std::map<uint32_t, PacketHandler> ShardPackets; static std::map<uint32_t, PacketHandler> ShardPackets;

View File

@ -14,7 +14,7 @@ struct PlayerView {
std::list<CNSocket*> viewable; std::list<CNSocket*> viewable;
std::list<int32_t> viewableNPCs; std::list<int32_t> viewableNPCs;
Player *plr; Player *plr;
uint64_t lastHeartbeat; time_t lastHeartbeat;
}; };

View File

@ -11,6 +11,7 @@ int settings::DBSAVEINTERVAL = 240;
int settings::SHARDPORT = 8002; int settings::SHARDPORT = 8002;
std::string settings::SHARDSERVERIP = "127.0.0.1"; std::string settings::SHARDSERVERIP = "127.0.0.1";
time_t settings::TIMEOUT = 60000;
int settings::PLAYERDISTANCE = 20000; int settings::PLAYERDISTANCE = 20000;
int settings::NPCDISTANCE = 16000; int settings::NPCDISTANCE = 16000;
@ -43,6 +44,7 @@ void settings::init() {
SHARDPORT = reader.GetInteger("shard", "port", SHARDPORT); SHARDPORT = reader.GetInteger("shard", "port", SHARDPORT);
SHARDSERVERIP = reader.Get("shard", "ip", "127.0.0.1"); SHARDSERVERIP = reader.Get("shard", "ip", "127.0.0.1");
DBSAVEINTERVAL = reader.GetInteger("login", "dbsaveinterval", DBSAVEINTERVAL); DBSAVEINTERVAL = reader.GetInteger("login", "dbsaveinterval", DBSAVEINTERVAL);
TIMEOUT = reader.GetInteger("shard", "timeout", TIMEOUT);
PLAYERDISTANCE = reader.GetInteger("shard", "playerdistance", PLAYERDISTANCE); PLAYERDISTANCE = reader.GetInteger("shard", "playerdistance", PLAYERDISTANCE);
NPCDISTANCE = reader.GetInteger("shard", "npcdistance", NPCDISTANCE); NPCDISTANCE = reader.GetInteger("shard", "npcdistance", NPCDISTANCE);
SPAWN_X = reader.GetInteger("shard", "spawnx", SPAWN_X); SPAWN_X = reader.GetInteger("shard", "spawnx", SPAWN_X);

View File

@ -7,6 +7,7 @@ namespace settings {
extern int DBSAVEINTERVAL; extern int DBSAVEINTERVAL;
extern int SHARDPORT; extern int SHARDPORT;
extern std::string SHARDSERVERIP; extern std::string SHARDSERVERIP;
extern time_t TIMEOUT;
extern int PLAYERDISTANCE; extern int PLAYERDISTANCE;
extern int NPCDISTANCE; extern int NPCDISTANCE;
extern int SPAWN_X; extern int SPAWN_X;