mirror of
https://github.com/DarkflameUniverse/DarkflameServer.git
synced 2024-11-24 14:37:25 +00:00
fix: signal handling (#1375)
* fix: signal handling * fix: flush WorldServer logger before main loop * fix: consolidate signal code
This commit is contained in:
parent
18feea5fed
commit
85672e060a
@ -1,6 +1,7 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
|
#include <csignal>
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
|
|
||||||
@ -28,7 +29,7 @@ namespace Game {
|
|||||||
Logger* logger = nullptr;
|
Logger* logger = nullptr;
|
||||||
dServer* server = nullptr;
|
dServer* server = nullptr;
|
||||||
dConfig* config = nullptr;
|
dConfig* config = nullptr;
|
||||||
bool shouldShutdown = false;
|
Game::signal_t lastSignal = 0;
|
||||||
std::mt19937 randomEngine;
|
std::mt19937 randomEngine;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -42,6 +43,9 @@ int main(int argc, char** argv) {
|
|||||||
Diagnostics::SetProcessFileName(argv[0]);
|
Diagnostics::SetProcessFileName(argv[0]);
|
||||||
Diagnostics::Initialize();
|
Diagnostics::Initialize();
|
||||||
|
|
||||||
|
std::signal(SIGINT, Game::OnSignal);
|
||||||
|
std::signal(SIGTERM, Game::OnSignal);
|
||||||
|
|
||||||
//Create all the objects we need to run our service:
|
//Create all the objects we need to run our service:
|
||||||
Game::logger = SetupLogger();
|
Game::logger = SetupLogger();
|
||||||
if (!Game::logger) return EXIT_FAILURE;
|
if (!Game::logger) return EXIT_FAILURE;
|
||||||
@ -74,6 +78,7 @@ int main(int argc, char** argv) {
|
|||||||
masterIP = masterInfo->ip;
|
masterIP = masterInfo->ip;
|
||||||
masterPort = masterInfo->port;
|
masterPort = masterInfo->port;
|
||||||
}
|
}
|
||||||
|
LOG("Master is at %s:%d", masterIP.c_str(), masterPort);
|
||||||
|
|
||||||
Game::randomEngine = std::mt19937(time(0));
|
Game::randomEngine = std::mt19937(time(0));
|
||||||
|
|
||||||
@ -83,7 +88,7 @@ int main(int argc, char** argv) {
|
|||||||
if (Game::config->GetValue("max_clients") != "") maxClients = std::stoi(Game::config->GetValue("max_clients"));
|
if (Game::config->GetValue("max_clients") != "") maxClients = std::stoi(Game::config->GetValue("max_clients"));
|
||||||
if (Game::config->GetValue("port") != "") ourPort = std::atoi(Game::config->GetValue("port").c_str());
|
if (Game::config->GetValue("port") != "") ourPort = std::atoi(Game::config->GetValue("port").c_str());
|
||||||
|
|
||||||
Game::server = new dServer(Game::config->GetValue("external_ip"), ourPort, 0, maxClients, false, true, Game::logger, masterIP, masterPort, ServerType::Auth, Game::config, &Game::shouldShutdown);
|
Game::server = new dServer(Game::config->GetValue("external_ip"), ourPort, 0, maxClients, false, true, Game::logger, masterIP, masterPort, ServerType::Auth, Game::config, &Game::lastSignal);
|
||||||
|
|
||||||
//Run it until server gets a kill message from Master:
|
//Run it until server gets a kill message from Master:
|
||||||
auto t = std::chrono::high_resolution_clock::now();
|
auto t = std::chrono::high_resolution_clock::now();
|
||||||
@ -96,13 +101,16 @@ int main(int argc, char** argv) {
|
|||||||
|
|
||||||
AuthPackets::LoadClaimCodes();
|
AuthPackets::LoadClaimCodes();
|
||||||
|
|
||||||
while (!Game::shouldShutdown) {
|
Game::logger->Flush(); // once immediately before main loop
|
||||||
|
while (!Game::ShouldShutdown()) {
|
||||||
//Check if we're still connected to master:
|
//Check if we're still connected to master:
|
||||||
if (!Game::server->GetIsConnectedToMaster()) {
|
if (!Game::server->GetIsConnectedToMaster()) {
|
||||||
framesSinceMasterDisconnect++;
|
framesSinceMasterDisconnect++;
|
||||||
|
|
||||||
if (framesSinceMasterDisconnect >= authFramerate)
|
if (framesSinceMasterDisconnect >= authFramerate) {
|
||||||
|
LOG("No connection to master!");
|
||||||
break; //Exit our loop, shut down.
|
break; //Exit our loop, shut down.
|
||||||
|
}
|
||||||
} else framesSinceMasterDisconnect = 0;
|
} else framesSinceMasterDisconnect = 0;
|
||||||
|
|
||||||
//In world we'd update our other systems here.
|
//In world we'd update our other systems here.
|
||||||
@ -141,6 +149,7 @@ int main(int argc, char** argv) {
|
|||||||
std::this_thread::sleep_until(t);
|
std::this_thread::sleep_until(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LOG("Exited Main Loop! (signal %d)", Game::lastSignal);
|
||||||
//Delete our objects here:
|
//Delete our objects here:
|
||||||
Database::Destroy("AuthServer");
|
Database::Destroy("AuthServer");
|
||||||
delete Game::server;
|
delete Game::server;
|
||||||
|
@ -33,7 +33,7 @@ namespace Game {
|
|||||||
dConfig* config = nullptr;
|
dConfig* config = nullptr;
|
||||||
dChatFilter* chatFilter = nullptr;
|
dChatFilter* chatFilter = nullptr;
|
||||||
AssetManager* assetManager = nullptr;
|
AssetManager* assetManager = nullptr;
|
||||||
bool shouldShutdown = false;
|
Game::signal_t lastSignal = 0;
|
||||||
std::mt19937 randomEngine;
|
std::mt19937 randomEngine;
|
||||||
PlayerContainer playerContainer;
|
PlayerContainer playerContainer;
|
||||||
}
|
}
|
||||||
@ -48,6 +48,9 @@ int main(int argc, char** argv) {
|
|||||||
Diagnostics::SetProcessFileName(argv[0]);
|
Diagnostics::SetProcessFileName(argv[0]);
|
||||||
Diagnostics::Initialize();
|
Diagnostics::Initialize();
|
||||||
|
|
||||||
|
std::signal(SIGINT, Game::OnSignal);
|
||||||
|
std::signal(SIGTERM, Game::OnSignal);
|
||||||
|
|
||||||
//Create all the objects we need to run our service:
|
//Create all the objects we need to run our service:
|
||||||
Game::logger = SetupLogger();
|
Game::logger = SetupLogger();
|
||||||
if (!Game::logger) return EXIT_FAILURE;
|
if (!Game::logger) return EXIT_FAILURE;
|
||||||
@ -101,7 +104,7 @@ int main(int argc, char** argv) {
|
|||||||
if (Game::config->GetValue("max_clients") != "") maxClients = std::stoi(Game::config->GetValue("max_clients"));
|
if (Game::config->GetValue("max_clients") != "") maxClients = std::stoi(Game::config->GetValue("max_clients"));
|
||||||
if (Game::config->GetValue("port") != "") ourPort = std::atoi(Game::config->GetValue("port").c_str());
|
if (Game::config->GetValue("port") != "") ourPort = std::atoi(Game::config->GetValue("port").c_str());
|
||||||
|
|
||||||
Game::server = new dServer(Game::config->GetValue("external_ip"), ourPort, 0, maxClients, false, true, Game::logger, masterIP, masterPort, ServerType::Chat, Game::config, &Game::shouldShutdown);
|
Game::server = new dServer(Game::config->GetValue("external_ip"), ourPort, 0, maxClients, false, true, Game::logger, masterIP, masterPort, ServerType::Chat, Game::config, &Game::lastSignal);
|
||||||
|
|
||||||
Game::chatFilter = new dChatFilter(Game::assetManager->GetResPath().string() + "/chatplus_en_us", bool(std::stoi(Game::config->GetValue("dont_generate_dcf"))));
|
Game::chatFilter = new dChatFilter(Game::assetManager->GetResPath().string() + "/chatplus_en_us", bool(std::stoi(Game::config->GetValue("dont_generate_dcf"))));
|
||||||
|
|
||||||
@ -118,7 +121,8 @@ int main(int argc, char** argv) {
|
|||||||
uint32_t framesSinceMasterDisconnect = 0;
|
uint32_t framesSinceMasterDisconnect = 0;
|
||||||
uint32_t framesSinceLastSQLPing = 0;
|
uint32_t framesSinceLastSQLPing = 0;
|
||||||
|
|
||||||
while (!Game::shouldShutdown) {
|
Game::logger->Flush(); // once immediately before main loop
|
||||||
|
while (!Game::ShouldShutdown()) {
|
||||||
//Check if we're still connected to master:
|
//Check if we're still connected to master:
|
||||||
if (!Game::server->GetIsConnectedToMaster()) {
|
if (!Game::server->GetIsConnectedToMaster()) {
|
||||||
framesSinceMasterDisconnect++;
|
framesSinceMasterDisconnect++;
|
||||||
|
@ -5,6 +5,7 @@ set(DCOMMON_SOURCES
|
|||||||
"dConfig.cpp"
|
"dConfig.cpp"
|
||||||
"Diagnostics.cpp"
|
"Diagnostics.cpp"
|
||||||
"Logger.cpp"
|
"Logger.cpp"
|
||||||
|
"Game.cpp"
|
||||||
"GeneralUtils.cpp"
|
"GeneralUtils.cpp"
|
||||||
"LDFFormat.cpp"
|
"LDFFormat.cpp"
|
||||||
"MD5.cpp"
|
"MD5.cpp"
|
||||||
|
7
dCommon/Game.cpp
Normal file
7
dCommon/Game.cpp
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
#include "Game.h"
|
||||||
|
|
||||||
|
namespace Game {
|
||||||
|
void OnSignal(int signal) {
|
||||||
|
lastSignal = signal;
|
||||||
|
}
|
||||||
|
}
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <random>
|
#include <random>
|
||||||
|
#include <csignal>
|
||||||
|
|
||||||
class dServer;
|
class dServer;
|
||||||
class Logger;
|
class Logger;
|
||||||
@ -16,6 +17,7 @@ class dZoneManager;
|
|||||||
class PlayerContainer;
|
class PlayerContainer;
|
||||||
|
|
||||||
namespace Game {
|
namespace Game {
|
||||||
|
using signal_t = volatile std::sig_atomic_t;
|
||||||
extern Logger* logger;
|
extern Logger* logger;
|
||||||
extern dServer* server;
|
extern dServer* server;
|
||||||
extern InstanceManager* im;
|
extern InstanceManager* im;
|
||||||
@ -25,9 +27,14 @@ namespace Game {
|
|||||||
extern RakPeerInterface* chatServer;
|
extern RakPeerInterface* chatServer;
|
||||||
extern AssetManager* assetManager;
|
extern AssetManager* assetManager;
|
||||||
extern SystemAddress chatSysAddr;
|
extern SystemAddress chatSysAddr;
|
||||||
extern bool shouldShutdown;
|
extern signal_t lastSignal;
|
||||||
extern EntityManager* entityManager;
|
extern EntityManager* entityManager;
|
||||||
extern dZoneManager* zoneManager;
|
extern dZoneManager* zoneManager;
|
||||||
extern PlayerContainer playerContainer;
|
extern PlayerContainer playerContainer;
|
||||||
extern std::string projectVersion;
|
extern std::string projectVersion;
|
||||||
|
|
||||||
|
inline bool ShouldShutdown() {
|
||||||
|
return lastSignal != 0;
|
||||||
|
}
|
||||||
|
void OnSignal(int signal);
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,8 @@
|
|||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
|
||||||
Writer::~Writer() {
|
Writer::~Writer() {
|
||||||
|
// Flush before we close
|
||||||
|
Flush();
|
||||||
// Dont try to close stdcout...
|
// Dont try to close stdcout...
|
||||||
if (!m_Outfile || m_IsConsoleWriter) return;
|
if (!m_Outfile || m_IsConsoleWriter) return;
|
||||||
|
|
||||||
|
@ -134,7 +134,7 @@ void InstanceManager::RemoveInstance(Instance* instance) {
|
|||||||
if (m_Instances[i] == instance) {
|
if (m_Instances[i] == instance) {
|
||||||
instance->SetShutdownComplete(true);
|
instance->SetShutdownComplete(true);
|
||||||
|
|
||||||
if (!Game::shouldShutdown) RedirectPendingRequests(instance);
|
if (!Game::ShouldShutdown()) RedirectPendingRequests(instance);
|
||||||
|
|
||||||
delete m_Instances[i];
|
delete m_Instances[i];
|
||||||
|
|
||||||
|
@ -47,12 +47,13 @@ namespace Game {
|
|||||||
InstanceManager* im = nullptr;
|
InstanceManager* im = nullptr;
|
||||||
dConfig* config = nullptr;
|
dConfig* config = nullptr;
|
||||||
AssetManager* assetManager = nullptr;
|
AssetManager* assetManager = nullptr;
|
||||||
bool shouldShutdown = false;
|
Game::signal_t lastSignal = 0;
|
||||||
|
bool universeShutdownRequested = false;
|
||||||
std::mt19937 randomEngine;
|
std::mt19937 randomEngine;
|
||||||
} //namespace Game
|
} //namespace Game
|
||||||
|
|
||||||
bool shutdownSequenceStarted = false;
|
bool shutdownSequenceStarted = false;
|
||||||
void ShutdownSequence(int32_t signal = -1);
|
int ShutdownSequence(int32_t signal = -1);
|
||||||
int32_t FinalizeShutdown(int32_t signal = -1);
|
int32_t FinalizeShutdown(int32_t signal = -1);
|
||||||
Logger* SetupLogger();
|
Logger* SetupLogger();
|
||||||
void HandlePacket(Packet* packet);
|
void HandlePacket(Packet* packet);
|
||||||
@ -73,8 +74,8 @@ int main(int argc, char** argv) {
|
|||||||
|
|
||||||
//Triggers the shutdown sequence at application exit
|
//Triggers the shutdown sequence at application exit
|
||||||
std::atexit([]() { ShutdownSequence(); });
|
std::atexit([]() { ShutdownSequence(); });
|
||||||
signal(SIGINT, [](int32_t signal) { ShutdownSequence(EXIT_FAILURE); });
|
std::signal(SIGINT, Game::OnSignal);
|
||||||
signal(SIGTERM, [](int32_t signal) { ShutdownSequence(EXIT_FAILURE); });
|
std::signal(SIGTERM, Game::OnSignal);
|
||||||
|
|
||||||
//Create all the objects we need to run our service:
|
//Create all the objects we need to run our service:
|
||||||
Game::logger = SetupLogger();
|
Game::logger = SetupLogger();
|
||||||
@ -286,7 +287,7 @@ int main(int argc, char** argv) {
|
|||||||
if (Game::config->GetValue("max_clients") != "") maxClients = std::stoi(Game::config->GetValue("max_clients"));
|
if (Game::config->GetValue("max_clients") != "") maxClients = std::stoi(Game::config->GetValue("max_clients"));
|
||||||
if (Game::config->GetValue("port") != "") ourPort = std::stoi(Game::config->GetValue("port"));
|
if (Game::config->GetValue("port") != "") ourPort = std::stoi(Game::config->GetValue("port"));
|
||||||
|
|
||||||
Game::server = new dServer(Game::config->GetValue("external_ip"), ourPort, 0, maxClients, true, false, Game::logger, "", 0, ServerType::Master, Game::config, &Game::shouldShutdown);
|
Game::server = new dServer(Game::config->GetValue("external_ip"), ourPort, 0, maxClients, true, false, Game::logger, "", 0, ServerType::Master, Game::config, &Game::lastSignal);
|
||||||
|
|
||||||
//Query for the database for a server labeled "master"
|
//Query for the database for a server labeled "master"
|
||||||
|
|
||||||
@ -321,7 +322,8 @@ int main(int argc, char** argv) {
|
|||||||
uint32_t framesSinceLastSQLPing = 0;
|
uint32_t framesSinceLastSQLPing = 0;
|
||||||
uint32_t framesSinceKillUniverseCommand = 0;
|
uint32_t framesSinceKillUniverseCommand = 0;
|
||||||
|
|
||||||
while (true) {
|
Game::logger->Flush();
|
||||||
|
while (!Game::ShouldShutdown()) {
|
||||||
//In world we'd update our other systems here.
|
//In world we'd update our other systems here.
|
||||||
|
|
||||||
//Check for packets here:
|
//Check for packets here:
|
||||||
@ -355,10 +357,10 @@ int main(int argc, char** argv) {
|
|||||||
framesSinceLastSQLPing++;
|
framesSinceLastSQLPing++;
|
||||||
|
|
||||||
//10m shutdown for universe kill command
|
//10m shutdown for universe kill command
|
||||||
if (Game::shouldShutdown) {
|
if (Game::universeShutdownRequested) {
|
||||||
if (framesSinceKillUniverseCommand >= shutdownUniverseTime) {
|
if (framesSinceKillUniverseCommand >= shutdownUniverseTime) {
|
||||||
//Break main loop and exit
|
//Break main loop and exit
|
||||||
break;
|
Game::lastSignal = -1;
|
||||||
} else
|
} else
|
||||||
framesSinceKillUniverseCommand++;
|
framesSinceKillUniverseCommand++;
|
||||||
}
|
}
|
||||||
@ -402,7 +404,7 @@ int main(int argc, char** argv) {
|
|||||||
t += std::chrono::milliseconds(masterFrameDelta);
|
t += std::chrono::milliseconds(masterFrameDelta);
|
||||||
std::this_thread::sleep_until(t);
|
std::this_thread::sleep_until(t);
|
||||||
}
|
}
|
||||||
return FinalizeShutdown(EXIT_SUCCESS);
|
return ShutdownSequence(EXIT_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger* SetupLogger() {
|
Logger* SetupLogger() {
|
||||||
@ -799,7 +801,7 @@ void HandlePacket(Packet* packet) {
|
|||||||
|
|
||||||
case eMasterMessageType::SHUTDOWN_UNIVERSE: {
|
case eMasterMessageType::SHUTDOWN_UNIVERSE: {
|
||||||
LOG("Received shutdown universe command, shutting down in 10 minutes.");
|
LOG("Received shutdown universe command, shutting down in 10 minutes.");
|
||||||
Game::shouldShutdown = true;
|
Game::universeShutdownRequested = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -809,9 +811,11 @@ void HandlePacket(Packet* packet) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShutdownSequence(int32_t signal) {
|
int ShutdownSequence(int32_t signal) {
|
||||||
|
LOG("Recieved Signal %d", signal);
|
||||||
if (shutdownSequenceStarted) {
|
if (shutdownSequenceStarted) {
|
||||||
return;
|
LOG("Duplicate Shutdown Sequence");
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!Game::im) {
|
if (!Game::im) {
|
||||||
@ -820,7 +824,7 @@ void ShutdownSequence(int32_t signal) {
|
|||||||
|
|
||||||
Game::im->SetIsShuttingDown(true);
|
Game::im->SetIsShuttingDown(true);
|
||||||
shutdownSequenceStarted = true;
|
shutdownSequenceStarted = true;
|
||||||
Game::shouldShutdown = true;
|
Game::lastSignal = -1;
|
||||||
|
|
||||||
{
|
{
|
||||||
CBITSTREAM;
|
CBITSTREAM;
|
||||||
@ -889,7 +893,7 @@ void ShutdownSequence(int32_t signal) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FinalizeShutdown(signal);
|
return FinalizeShutdown(signal);
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t FinalizeShutdown(int32_t signal) {
|
int32_t FinalizeShutdown(int32_t signal) {
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
#include "BinaryPathFinder.h"
|
#include "BinaryPathFinder.h"
|
||||||
|
|
||||||
void StartChatServer() {
|
void StartChatServer() {
|
||||||
if (Game::shouldShutdown) {
|
if (Game::ShouldShutdown()) {
|
||||||
LOG("Currently shutting down. Chat will not be restarted.");
|
LOG("Currently shutting down. Chat will not be restarted.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -24,7 +24,7 @@ void StartChatServer() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void StartAuthServer() {
|
void StartAuthServer() {
|
||||||
if (Game::shouldShutdown) {
|
if (Game::ShouldShutdown()) {
|
||||||
LOG("Currently shutting down. Auth will not be restarted.");
|
LOG("Currently shutting down. Auth will not be restarted.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -55,7 +55,9 @@ void AuthPackets::SendHandshake(dServer* server, const SystemAddress& sysAddr, c
|
|||||||
RakNet::BitStream bitStream;
|
RakNet::BitStream bitStream;
|
||||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::SERVER, eServerMessageType::VERSION_CONFIRM);
|
BitStreamUtils::WriteHeader(bitStream, eConnectionType::SERVER, eServerMessageType::VERSION_CONFIRM);
|
||||||
uint32_t netVersion;
|
uint32_t netVersion;
|
||||||
if (!GeneralUtils::TryParse(Game::config->GetValue("client_net_version"), netVersion)) {
|
const std::string& expectedVersion = Game::config->GetValue("client_net_version");
|
||||||
|
LOG("Expected Version: '%s'", expectedVersion.c_str());
|
||||||
|
if (!GeneralUtils::TryParse(expectedVersion, netVersion)) {
|
||||||
LOG("Failed to parse client_net_version. Cannot authenticate to %s:%i", nextServerIP.c_str(), nextServerPort);
|
LOG("Failed to parse client_net_version. Cannot authenticate to %s:%i", nextServerIP.c_str(), nextServerPort);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -39,7 +39,7 @@ public:
|
|||||||
}
|
}
|
||||||
} ReceiveDownloadCompleteCB;
|
} ReceiveDownloadCompleteCB;
|
||||||
|
|
||||||
dServer::dServer(const std::string& ip, int port, int instanceID, int maxConnections, bool isInternal, bool useEncryption, Logger* logger, const std::string masterIP, int masterPort, ServerType serverType, dConfig* config, bool* shouldShutdown, unsigned int zoneID) {
|
dServer::dServer(const std::string& ip, int port, int instanceID, int maxConnections, bool isInternal, bool useEncryption, Logger* logger, const std::string masterIP, int masterPort, ServerType serverType, dConfig* config, Game::signal_t* lastSignal, unsigned int zoneID) {
|
||||||
mIP = ip;
|
mIP = ip;
|
||||||
mPort = port;
|
mPort = port;
|
||||||
mZoneID = zoneID;
|
mZoneID = zoneID;
|
||||||
@ -55,7 +55,7 @@ dServer::dServer(const std::string& ip, int port, int instanceID, int maxConnect
|
|||||||
mReplicaManager = nullptr;
|
mReplicaManager = nullptr;
|
||||||
mServerType = serverType;
|
mServerType = serverType;
|
||||||
mConfig = config;
|
mConfig = config;
|
||||||
mShouldShutdown = shouldShutdown;
|
mShouldShutdown = lastSignal;
|
||||||
//Attempt to start our server here:
|
//Attempt to start our server here:
|
||||||
mIsOkay = Startup();
|
mIsOkay = Startup();
|
||||||
|
|
||||||
@ -75,7 +75,9 @@ dServer::dServer(const std::string& ip, int port, int instanceID, int maxConnect
|
|||||||
//Connect to master if we are not master:
|
//Connect to master if we are not master:
|
||||||
if (serverType != ServerType::Master) {
|
if (serverType != ServerType::Master) {
|
||||||
SetupForMasterConnection();
|
SetupForMasterConnection();
|
||||||
ConnectToMaster();
|
if (!ConnectToMaster()) {
|
||||||
|
LOG("Failed ConnectToMaster!");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Set up Replica if we're a world server:
|
//Set up Replica if we're a world server:
|
||||||
@ -129,7 +131,7 @@ Packet* dServer::ReceiveFromMaster() {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case eMasterMessageType::SHUTDOWN:
|
case eMasterMessageType::SHUTDOWN:
|
||||||
*mShouldShutdown = true;
|
*mShouldShutdown = -2;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
//When we handle these packets in World instead dServer, we just return the packet's pointer.
|
//When we handle these packets in World instead dServer, we just return the packet's pointer.
|
||||||
@ -236,10 +238,12 @@ void dServer::Shutdown() {
|
|||||||
void dServer::SetupForMasterConnection() {
|
void dServer::SetupForMasterConnection() {
|
||||||
mMasterSocketDescriptor = SocketDescriptor(uint16_t(mPort + 1), 0);
|
mMasterSocketDescriptor = SocketDescriptor(uint16_t(mPort + 1), 0);
|
||||||
mMasterPeer = RakNetworkFactory::GetRakPeerInterface();
|
mMasterPeer = RakNetworkFactory::GetRakPeerInterface();
|
||||||
mMasterPeer->Startup(1, 30, &mMasterSocketDescriptor, 1);
|
bool ret = mMasterPeer->Startup(1, 30, &mMasterSocketDescriptor, 1);
|
||||||
|
if (!ret) LOG("Failed MasterPeer Startup!");
|
||||||
}
|
}
|
||||||
|
|
||||||
bool dServer::ConnectToMaster() {
|
bool dServer::ConnectToMaster() {
|
||||||
|
//LOG("Connection to Master %s:%d", mMasterIP.c_str(), mMasterPort);
|
||||||
return mMasterPeer->Connect(mMasterIP.c_str(), mMasterPort, "3.25 DARKFLAME1", 15);
|
return mMasterPeer->Connect(mMasterIP.c_str(), mMasterPort, "3.25 DARKFLAME1", 15);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <csignal>
|
||||||
#include "RakPeerInterface.h"
|
#include "RakPeerInterface.h"
|
||||||
#include "ReplicaManager.h"
|
#include "ReplicaManager.h"
|
||||||
#include "NetworkIDManager.h"
|
#include "NetworkIDManager.h"
|
||||||
@ -15,6 +16,10 @@ enum class ServerType : uint32_t {
|
|||||||
World
|
World
|
||||||
};
|
};
|
||||||
|
|
||||||
|
namespace Game {
|
||||||
|
using signal_t = volatile std::sig_atomic_t;
|
||||||
|
}
|
||||||
|
|
||||||
class dServer {
|
class dServer {
|
||||||
public:
|
public:
|
||||||
// Default constructor should only used for testing!
|
// Default constructor should only used for testing!
|
||||||
@ -31,7 +36,7 @@ public:
|
|||||||
int masterPort,
|
int masterPort,
|
||||||
ServerType serverType,
|
ServerType serverType,
|
||||||
dConfig* config,
|
dConfig* config,
|
||||||
bool* shouldShutdown,
|
Game::signal_t* shouldShutdown,
|
||||||
unsigned int zoneID = 0);
|
unsigned int zoneID = 0);
|
||||||
~dServer();
|
~dServer();
|
||||||
|
|
||||||
@ -81,9 +86,9 @@ private:
|
|||||||
NetworkIDManager* mNetIDManager = nullptr;
|
NetworkIDManager* mNetIDManager = nullptr;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether or not to shut down the server. Pointer to Game::shouldShutdown.
|
* Whether or not to shut down the server. Pointer to Game::lastSignal.
|
||||||
*/
|
*/
|
||||||
bool* mShouldShutdown = nullptr;
|
Game::signal_t* mShouldShutdown = nullptr;
|
||||||
SocketDescriptor mSocketDescriptor;
|
SocketDescriptor mSocketDescriptor;
|
||||||
std::string mIP;
|
std::string mIP;
|
||||||
int mPort;
|
int mPort;
|
||||||
|
@ -88,7 +88,7 @@ namespace Game {
|
|||||||
RakPeerInterface* chatServer = nullptr;
|
RakPeerInterface* chatServer = nullptr;
|
||||||
std::mt19937 randomEngine;
|
std::mt19937 randomEngine;
|
||||||
SystemAddress chatSysAddr;
|
SystemAddress chatSysAddr;
|
||||||
bool shouldShutdown = false;
|
Game::signal_t lastSignal = 0;
|
||||||
EntityManager* entityManager = nullptr;
|
EntityManager* entityManager = nullptr;
|
||||||
dZoneManager* zoneManager = nullptr;
|
dZoneManager* zoneManager = nullptr;
|
||||||
std::string projectVersion = PROJECT_VERSION;
|
std::string projectVersion = PROJECT_VERSION;
|
||||||
@ -124,8 +124,8 @@ int main(int argc, char** argv) {
|
|||||||
// Triggers the shutdown sequence at application exit
|
// Triggers the shutdown sequence at application exit
|
||||||
std::atexit(WorldShutdownSequence);
|
std::atexit(WorldShutdownSequence);
|
||||||
|
|
||||||
signal(SIGINT, [](int) { WorldShutdownSequence(); });
|
std::signal(SIGINT, Game::OnSignal);
|
||||||
signal(SIGTERM, [](int) { WorldShutdownSequence(); });
|
std::signal(SIGTERM, Game::OnSignal);
|
||||||
|
|
||||||
uint32_t zoneID = 1000;
|
uint32_t zoneID = 1000;
|
||||||
uint32_t cloneID = 0;
|
uint32_t cloneID = 0;
|
||||||
@ -212,7 +212,7 @@ int main(int argc, char** argv) {
|
|||||||
UserManager::Instance()->Initialize();
|
UserManager::Instance()->Initialize();
|
||||||
Game::chatFilter = new dChatFilter(Game::assetManager->GetResPath().string() + "/chatplus_en_us", bool(std::stoi(Game::config->GetValue("dont_generate_dcf"))));
|
Game::chatFilter = new dChatFilter(Game::assetManager->GetResPath().string() + "/chatplus_en_us", bool(std::stoi(Game::config->GetValue("dont_generate_dcf"))));
|
||||||
|
|
||||||
Game::server = new dServer(masterIP, ourPort, instanceID, maxClients, false, true, Game::logger, masterIP, masterPort, ServerType::World, Game::config, &Game::shouldShutdown, zoneID);
|
Game::server = new dServer(masterIP, ourPort, instanceID, maxClients, false, true, Game::logger, masterIP, masterPort, ServerType::World, Game::config, &Game::lastSignal, zoneID);
|
||||||
|
|
||||||
//Connect to the chat server:
|
//Connect to the chat server:
|
||||||
uint32_t chatPort = 1501;
|
uint32_t chatPort = 1501;
|
||||||
@ -313,6 +313,8 @@ int main(int argc, char** argv) {
|
|||||||
uint32_t saveTime = 10 * 60 * currentFramerate; // 10 minutes in frames
|
uint32_t saveTime = 10 * 60 * currentFramerate; // 10 minutes in frames
|
||||||
uint32_t sqlPingTime = 10 * 60 * currentFramerate; // 10 minutes in frames
|
uint32_t sqlPingTime = 10 * 60 * currentFramerate; // 10 minutes in frames
|
||||||
uint32_t emptyShutdownTime = (cloneID == 0 ? 30 : 5) * 60 * currentFramerate; // 30 minutes for main worlds, 5 for all others.
|
uint32_t emptyShutdownTime = (cloneID == 0 ? 30 : 5) * 60 * currentFramerate; // 30 minutes for main worlds, 5 for all others.
|
||||||
|
|
||||||
|
Game::logger->Flush(); // once immediately before the main loop
|
||||||
while (true) {
|
while (true) {
|
||||||
Metrics::StartMeasurement(MetricVariable::Frame);
|
Metrics::StartMeasurement(MetricVariable::Frame);
|
||||||
Metrics::StartMeasurement(MetricVariable::GameLoop);
|
Metrics::StartMeasurement(MetricVariable::GameLoop);
|
||||||
@ -363,9 +365,9 @@ int main(int argc, char** argv) {
|
|||||||
if (!Game::server->GetIsConnectedToMaster()) {
|
if (!Game::server->GetIsConnectedToMaster()) {
|
||||||
framesSinceMasterDisconnect++;
|
framesSinceMasterDisconnect++;
|
||||||
|
|
||||||
if (framesSinceMasterDisconnect >= noMasterConnectionTimeout && !Game::shouldShutdown) {
|
if (framesSinceMasterDisconnect >= noMasterConnectionTimeout && !Game::ShouldShutdown()) {
|
||||||
LOG("Game loop running but no connection to master for %d frames, shutting down", noMasterConnectionTimeout);
|
LOG("Game loop running but no connection to master for %d frames, shutting down", noMasterConnectionTimeout);
|
||||||
Game::shouldShutdown = true;
|
Game::lastSignal = -1;
|
||||||
}
|
}
|
||||||
} else framesSinceMasterDisconnect = 0;
|
} else framesSinceMasterDisconnect = 0;
|
||||||
|
|
||||||
@ -460,7 +462,7 @@ int main(int argc, char** argv) {
|
|||||||
|
|
||||||
//If we haven't had any players for a while, time out and shut down:
|
//If we haven't had any players for a while, time out and shut down:
|
||||||
if (framesSinceLastUser >= emptyShutdownTime) {
|
if (framesSinceLastUser >= emptyShutdownTime) {
|
||||||
Game::shouldShutdown = true;
|
Game::lastSignal = -1;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
framesSinceLastUser = 0;
|
framesSinceLastUser = 0;
|
||||||
@ -513,7 +515,7 @@ int main(int argc, char** argv) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Game::shouldShutdown && !worldShutdownSequenceComplete) {
|
if (Game::ShouldShutdown() && !worldShutdownSequenceComplete) {
|
||||||
WorldShutdownProcess(zoneID);
|
WorldShutdownProcess(zoneID);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -822,7 +824,7 @@ void HandlePacket(Packet* packet) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
case eMasterMessageType::SHUTDOWN: {
|
case eMasterMessageType::SHUTDOWN: {
|
||||||
Game::shouldShutdown = true;
|
Game::lastSignal = -1;
|
||||||
LOG("Got shutdown request from master, zone (%i), instance (%i)", Game::server->GetZoneID(), Game::server->GetInstanceID());
|
LOG("Got shutdown request from master, zone (%i), instance (%i)", Game::server->GetZoneID(), Game::server->GetInstanceID());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1289,9 +1291,9 @@ void WorldShutdownProcess(uint32_t zoneId) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void WorldShutdownSequence() {
|
void WorldShutdownSequence() {
|
||||||
Game::shouldShutdown = true;
|
Game::lastSignal = -1;
|
||||||
#ifndef DARKFLAME_PLATFORM_WIN32
|
#ifndef DARKFLAME_PLATFORM_WIN32
|
||||||
if (Game::shouldShutdown || worldShutdownSequenceComplete)
|
if (Game::ShouldShutdown() || worldShutdownSequenceComplete)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
|
Loading…
Reference in New Issue
Block a user