mirror of
https://github.com/DarkflameUniverse/DarkflameServer.git
synced 2024-11-13 19:58:21 +00:00
Properly exit
Properly exit based on the path taken to shutdown master. Tested that shutting down through sigint or sigterm returns -1 Tested that a segfault exits the program properly Need to test that players who are trying to connect while master is shutting down are not able to spawn more child worlds.
This commit is contained in:
parent
435761f64b
commit
1afe717563
@ -84,7 +84,7 @@ int main(int argc, char** argv) {
|
|||||||
if (config.GetValue("max_clients") != "") maxClients = std::stoi(config.GetValue("max_clients"));
|
if (config.GetValue("max_clients") != "") maxClients = std::stoi(config.GetValue("max_clients"));
|
||||||
if (config.GetValue("port") != "") ourPort = std::atoi(config.GetValue("port").c_str());
|
if (config.GetValue("port") != "") ourPort = std::atoi(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::shouldShutdown);
|
||||||
|
|
||||||
//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();
|
||||||
|
@ -104,7 +104,7 @@ int main(int argc, char** argv) {
|
|||||||
if (config.GetValue("max_clients") != "") maxClients = std::stoi(config.GetValue("max_clients"));
|
if (config.GetValue("max_clients") != "") maxClients = std::stoi(config.GetValue("max_clients"));
|
||||||
if (config.GetValue("port") != "") ourPort = std::atoi(config.GetValue("port").c_str());
|
if (config.GetValue("port") != "") ourPort = std::atoi(config.GetValue("port").c_str());
|
||||||
|
|
||||||
Game::server = new dServer(config.GetValue("external_ip"), ourPort, 0, maxClients, false, true, Game::logger, masterIP, masterPort, ServerType::Chat, Game::config, Game::shouldShutdown);
|
Game::server = new dServer(config.GetValue("external_ip"), ourPort, 0, maxClients, false, true, Game::logger, masterIP, masterPort, ServerType::Chat, Game::config, &Game::shouldShutdown);
|
||||||
|
|
||||||
Game::chatFilter = new dChatFilter(Game::assetManager->GetResPath().string() + "/chatplus_en_us", bool(std::stoi(config.GetValue("dont_generate_dcf"))));
|
Game::chatFilter = new dChatFilter(Game::assetManager->GetResPath().string() + "/chatplus_en_us", bool(std::stoi(config.GetValue("dont_generate_dcf"))));
|
||||||
|
|
||||||
|
@ -150,7 +150,7 @@ void InstanceManager::RemoveInstance(Instance* instance) {
|
|||||||
if (m_Instances[i] == instance) {
|
if (m_Instances[i] == instance) {
|
||||||
instance->SetShutdownComplete(true);
|
instance->SetShutdownComplete(true);
|
||||||
|
|
||||||
RedirectPendingRequests(instance);
|
if (!Game::shouldShutdown) RedirectPendingRequests(instance);
|
||||||
|
|
||||||
delete m_Instances[i];
|
delete m_Instances[i];
|
||||||
|
|
||||||
|
@ -52,13 +52,14 @@ namespace Game {
|
|||||||
} //namespace Game
|
} //namespace Game
|
||||||
|
|
||||||
bool shutdownSequenceStarted = false;
|
bool shutdownSequenceStarted = false;
|
||||||
void ShutdownSequence();
|
void ShutdownSequence(int signal = -1);
|
||||||
int FinalizeShutdown();
|
int FinalizeShutdown(int signal = -1);
|
||||||
dLogger* SetupLogger();
|
dLogger* SetupLogger();
|
||||||
void StartAuthServer();
|
void StartAuthServer();
|
||||||
void StartChatServer();
|
void StartChatServer();
|
||||||
void HandlePacket(Packet* packet);
|
void HandlePacket(Packet* packet);
|
||||||
std::map<uint32_t, std::string> activeSessions;
|
std::map<uint32_t, std::string> activeSessions;
|
||||||
|
SystemAddress authServerMasterPeerSysAddr;
|
||||||
SystemAddress chatServerMasterPeerSysAddr;
|
SystemAddress chatServerMasterPeerSysAddr;
|
||||||
|
|
||||||
int main(int argc, char** argv) {
|
int main(int argc, char** argv) {
|
||||||
@ -71,9 +72,9 @@ int main(int argc, char** argv) {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
//Triggers the shutdown sequence at application exit
|
//Triggers the shutdown sequence at application exit
|
||||||
std::atexit(ShutdownSequence);
|
std::atexit([]() { ShutdownSequence(); });
|
||||||
signal(SIGINT, [](int) { ShutdownSequence(); });
|
signal(SIGINT, [](int signal) { ShutdownSequence(EXIT_FAILURE); });
|
||||||
signal(SIGTERM, [](int) { ShutdownSequence(); });
|
signal(SIGTERM, [](int signal) { ShutdownSequence(EXIT_FAILURE); });
|
||||||
|
|
||||||
//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();
|
||||||
@ -216,7 +217,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(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::shouldShutdown);
|
||||||
|
|
||||||
//Query for the database for a server labeled "master"
|
//Query for the database for a server labeled "master"
|
||||||
auto* masterLookupStatement = Database::CreatePreppedStmt("SELECT id FROM `servers` WHERE `name` = 'master'");
|
auto* masterLookupStatement = Database::CreatePreppedStmt("SELECT id FROM `servers` WHERE `name` = 'master'");
|
||||||
@ -253,8 +254,8 @@ int main(int argc, char** argv) {
|
|||||||
if (Game::config->GetValue("prestart_servers") != "" && Game::config->GetValue("prestart_servers") == "1") {
|
if (Game::config->GetValue("prestart_servers") != "" && Game::config->GetValue("prestart_servers") == "1") {
|
||||||
StartChatServer();
|
StartChatServer();
|
||||||
|
|
||||||
Game::im->GetInstance(0, false, 0)->SetIsReady(true);
|
Game::im->GetInstance(0, false, 0);
|
||||||
Game::im->GetInstance(1000, false, 0)->SetIsReady(true);
|
Game::im->GetInstance(1000, false, 0);
|
||||||
|
|
||||||
StartAuthServer();
|
StartAuthServer();
|
||||||
}
|
}
|
||||||
@ -350,9 +351,7 @@ int main(int argc, char** argv) {
|
|||||||
t += std::chrono::milliseconds(highFrameRate);
|
t += std::chrono::milliseconds(highFrameRate);
|
||||||
std::this_thread::sleep_until(t);
|
std::this_thread::sleep_until(t);
|
||||||
}
|
}
|
||||||
FinalizeShutdown();
|
return FinalizeShutdown(EXIT_SUCCESS);
|
||||||
exit(EXIT_SUCCESS);
|
|
||||||
return EXIT_SUCCESS;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dLogger* SetupLogger() {
|
dLogger* SetupLogger() {
|
||||||
@ -381,9 +380,15 @@ void HandlePacket(Packet* packet) {
|
|||||||
Game::im->RemoveInstance(instance); //Delete the old
|
Game::im->RemoveInstance(instance); //Delete the old
|
||||||
}
|
}
|
||||||
|
|
||||||
if (packet->systemAddress == chatServerMasterPeerSysAddr && !Game::shouldShutdown) {
|
if (packet->systemAddress == chatServerMasterPeerSysAddr) {
|
||||||
|
chatServerMasterPeerSysAddr = UNASSIGNED_SYSTEM_ADDRESS;
|
||||||
StartChatServer();
|
StartChatServer();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (packet->systemAddress == authServerMasterPeerSysAddr) {
|
||||||
|
authServerMasterPeerSysAddr = UNASSIGNED_SYSTEM_ADDRESS;
|
||||||
|
StartAuthServer();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (packet->data[0] == ID_CONNECTION_LOST) {
|
if (packet->data[0] == ID_CONNECTION_LOST) {
|
||||||
@ -397,9 +402,15 @@ void HandlePacket(Packet* packet) {
|
|||||||
//Game::im->GetInstance(zoneID.GetMapID(), false, 0); //Create the new
|
//Game::im->GetInstance(zoneID.GetMapID(), false, 0); //Create the new
|
||||||
}
|
}
|
||||||
|
|
||||||
if (packet->systemAddress == chatServerMasterPeerSysAddr && !Game::shouldShutdown) {
|
if (packet->systemAddress == chatServerMasterPeerSysAddr) {
|
||||||
|
chatServerMasterPeerSysAddr = UNASSIGNED_SYSTEM_ADDRESS;
|
||||||
StartChatServer();
|
StartChatServer();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (packet->systemAddress == authServerMasterPeerSysAddr) {
|
||||||
|
authServerMasterPeerSysAddr = UNASSIGNED_SYSTEM_ADDRESS;
|
||||||
|
StartAuthServer();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (packet->data[1] == MASTER) {
|
if (packet->data[1] == MASTER) {
|
||||||
@ -495,6 +506,14 @@ void HandlePacket(Packet* packet) {
|
|||||||
chatServerMasterPeerSysAddr = copy;
|
chatServerMasterPeerSysAddr = copy;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (theirServerType == ServerType::Auth) {
|
||||||
|
SystemAddress copy;
|
||||||
|
copy.binaryAddress = packet->systemAddress.binaryAddress;
|
||||||
|
copy.port = packet->systemAddress.port;
|
||||||
|
|
||||||
|
authServerMasterPeerSysAddr = copy;
|
||||||
|
}
|
||||||
|
|
||||||
Game::logger->Log("MasterServer", "Received server info, instance: %i port: %i", theirInstanceID, theirPort);
|
Game::logger->Log("MasterServer", "Received server info, instance: %i port: %i", theirInstanceID, theirPort);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@ -726,10 +745,14 @@ void HandlePacket(Packet* packet) {
|
|||||||
default:
|
default:
|
||||||
Game::logger->Log("MasterServer", "Unknown master packet ID from server: %i", packet->data[3]);
|
Game::logger->Log("MasterServer", "Unknown master packet ID from server: %i", packet->data[3]);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void StartChatServer() {
|
void StartChatServer() {
|
||||||
|
if (Game::shouldShutdown) {
|
||||||
|
Game::logger->Log("MasterServer", "Currently shutting down. Chat will not be restarted.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
//macOS doesn't need sudo to run on ports < 1024
|
//macOS doesn't need sudo to run on ports < 1024
|
||||||
system(((BinaryPathFinder::GetBinaryDir() / "ChatServer").string() + "&").c_str());
|
system(((BinaryPathFinder::GetBinaryDir() / "ChatServer").string() + "&").c_str());
|
||||||
@ -742,9 +765,13 @@ void StartChatServer() {
|
|||||||
system(((BinaryPathFinder::GetBinaryDir() / "ChatServer").string() + "&").c_str());
|
system(((BinaryPathFinder::GetBinaryDir() / "ChatServer").string() + "&").c_str());
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void StartAuthServer() {
|
void StartAuthServer() {
|
||||||
|
if (Game::shouldShutdown) {
|
||||||
|
Game::logger->Log("MasterServer", "Currently shutting down. Auth will not be restarted.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
system(((BinaryPathFinder::GetBinaryDir() / "AuthServer").string() + "&").c_str());
|
system(((BinaryPathFinder::GetBinaryDir() / "AuthServer").string() + "&").c_str());
|
||||||
#elif _WIN32
|
#elif _WIN32
|
||||||
@ -758,12 +785,13 @@ void StartAuthServer() {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShutdownSequence() {
|
void ShutdownSequence(int signal) {
|
||||||
if (shutdownSequenceStarted) {
|
if (shutdownSequenceStarted) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
shutdownSequenceStarted = true;
|
shutdownSequenceStarted = true;
|
||||||
|
Game::shouldShutdown = true;
|
||||||
|
|
||||||
{
|
{
|
||||||
CBITSTREAM;
|
CBITSTREAM;
|
||||||
@ -782,7 +810,14 @@ void ShutdownSequence() {
|
|||||||
auto ticks = 0;
|
auto ticks = 0;
|
||||||
|
|
||||||
if (!Game::im) {
|
if (!Game::im) {
|
||||||
exit(EXIT_SUCCESS);
|
FinalizeShutdown(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// A server might not be finished spinning up yet, remove all of those here.
|
||||||
|
for (auto instance : Game::im->GetInstances()) {
|
||||||
|
if (!instance->GetIsReady()) {
|
||||||
|
Game::im->RemoveInstance(instance);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto instance : Game::im->GetInstances()) {
|
for (auto instance : Game::im->GetInstances()) {
|
||||||
@ -792,7 +827,6 @@ void ShutdownSequence() {
|
|||||||
Game::logger->Log("MasterServer", "Attempting to shutdown instances, max 60 seconds...");
|
Game::logger->Log("MasterServer", "Attempting to shutdown instances, max 60 seconds...");
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
|
|
||||||
auto packet = Game::server->Receive();
|
auto packet = Game::server->Receive();
|
||||||
if (packet) {
|
if (packet) {
|
||||||
HandlePacket(packet);
|
HandlePacket(packet);
|
||||||
@ -812,7 +846,7 @@ void ShutdownSequence() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (done) {
|
if (done && authServerMasterPeerSysAddr == UNASSIGNED_SYSTEM_ADDRESS && chatServerMasterPeerSysAddr == UNASSIGNED_SYSTEM_ADDRESS) {
|
||||||
Game::logger->Log("MasterServer", "Finished shutting down MasterServer!");
|
Game::logger->Log("MasterServer", "Finished shutting down MasterServer!");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -828,10 +862,10 @@ void ShutdownSequence() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FinalizeShutdown();
|
FinalizeShutdown(signal);
|
||||||
}
|
}
|
||||||
|
|
||||||
int FinalizeShutdown() {
|
int FinalizeShutdown(int signal) {
|
||||||
//Delete our objects here:
|
//Delete our objects here:
|
||||||
Database::Destroy("MasterServer");
|
Database::Destroy("MasterServer");
|
||||||
if (Game::config) delete Game::config;
|
if (Game::config) delete Game::config;
|
||||||
@ -839,6 +873,6 @@ int FinalizeShutdown() {
|
|||||||
if (Game::server) delete Game::server;
|
if (Game::server) delete Game::server;
|
||||||
if (Game::logger) delete Game::logger;
|
if (Game::logger) delete Game::logger;
|
||||||
|
|
||||||
exit(EXIT_SUCCESS);
|
if (signal != EXIT_SUCCESS) exit(signal);
|
||||||
return EXIT_SUCCESS;
|
return signal;
|
||||||
}
|
}
|
||||||
|
@ -36,7 +36,7 @@ public:
|
|||||||
}
|
}
|
||||||
} ReceiveDownloadCompleteCB;
|
} ReceiveDownloadCompleteCB;
|
||||||
|
|
||||||
dServer::dServer(const std::string& ip, int port, int instanceID, int maxConnections, bool isInternal, bool useEncryption, dLogger* 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, dLogger* logger, const std::string masterIP, int masterPort, ServerType serverType, dConfig* config, bool* shouldShutdown, unsigned int zoneID) {
|
||||||
mIP = ip;
|
mIP = ip;
|
||||||
mPort = port;
|
mPort = port;
|
||||||
mZoneID = zoneID;
|
mZoneID = zoneID;
|
||||||
@ -52,7 +52,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 = shouldShutdown;
|
||||||
//Attempt to start our server here:
|
//Attempt to start our server here:
|
||||||
mIsOkay = Startup();
|
mIsOkay = Startup();
|
||||||
|
|
||||||
|
@ -30,7 +30,7 @@ public:
|
|||||||
int masterPort,
|
int masterPort,
|
||||||
ServerType serverType,
|
ServerType serverType,
|
||||||
dConfig* config,
|
dConfig* config,
|
||||||
bool& shouldShutdown,
|
bool* shouldShutdown,
|
||||||
unsigned int zoneID = 0);
|
unsigned int zoneID = 0);
|
||||||
~dServer();
|
~dServer();
|
||||||
|
|
||||||
|
@ -208,7 +208,7 @@ int main(int argc, char** argv) {
|
|||||||
LootGenerator::Instance();
|
LootGenerator::Instance();
|
||||||
Game::chatFilter = new dChatFilter(Game::assetManager->GetResPath().string() + "/chatplus_en_us", bool(std::stoi(config.GetValue("dont_generate_dcf"))));
|
Game::chatFilter = new dChatFilter(Game::assetManager->GetResPath().string() + "/chatplus_en_us", bool(std::stoi(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::shouldShutdown, zoneID);
|
||||||
|
|
||||||
//Connect to the chat server:
|
//Connect to the chat server:
|
||||||
int chatPort = 1501;
|
int chatPort = 1501;
|
||||||
|
Loading…
Reference in New Issue
Block a user