|
|
|
@@ -23,7 +23,7 @@
|
|
|
|
|
#include "Diagnostics.h"
|
|
|
|
|
#include "dCommonVars.h"
|
|
|
|
|
#include "dConfig.h"
|
|
|
|
|
#include "dLogger.h"
|
|
|
|
|
#include "Logger.h"
|
|
|
|
|
#include "dServer.h"
|
|
|
|
|
#include "AssetManager.h"
|
|
|
|
|
#include "BinaryPathFinder.h"
|
|
|
|
@@ -45,7 +45,7 @@
|
|
|
|
|
#include "BitStreamUtils.h"
|
|
|
|
|
|
|
|
|
|
namespace Game {
|
|
|
|
|
dLogger* logger = nullptr;
|
|
|
|
|
Logger* logger = nullptr;
|
|
|
|
|
dServer* server = nullptr;
|
|
|
|
|
InstanceManager* im = nullptr;
|
|
|
|
|
dConfig* config = nullptr;
|
|
|
|
@@ -57,7 +57,7 @@ namespace Game {
|
|
|
|
|
bool shutdownSequenceStarted = false;
|
|
|
|
|
void ShutdownSequence(int32_t signal = -1);
|
|
|
|
|
int32_t FinalizeShutdown(int32_t signal = -1);
|
|
|
|
|
dLogger* SetupLogger();
|
|
|
|
|
Logger* SetupLogger();
|
|
|
|
|
void StartAuthServer();
|
|
|
|
|
void StartChatServer();
|
|
|
|
|
void HandlePacket(Packet* packet);
|
|
|
|
@@ -86,27 +86,27 @@ int main(int argc, char** argv) {
|
|
|
|
|
if (!Game::logger) return EXIT_FAILURE;
|
|
|
|
|
|
|
|
|
|
if (!std::filesystem::exists(BinaryPathFinder::GetBinaryDir() / "authconfig.ini")) {
|
|
|
|
|
Game::logger->Log("MasterServer", "Couldnt find authconfig.ini");
|
|
|
|
|
LOG("Couldnt find authconfig.ini");
|
|
|
|
|
return EXIT_FAILURE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!std::filesystem::exists(BinaryPathFinder::GetBinaryDir() / "chatconfig.ini")) {
|
|
|
|
|
Game::logger->Log("MasterServer", "Couldnt find chatconfig.ini");
|
|
|
|
|
LOG("Couldnt find chatconfig.ini");
|
|
|
|
|
return EXIT_FAILURE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!std::filesystem::exists(BinaryPathFinder::GetBinaryDir() / "masterconfig.ini")) {
|
|
|
|
|
Game::logger->Log("MasterServer", "Couldnt find masterconfig.ini");
|
|
|
|
|
LOG("Couldnt find masterconfig.ini");
|
|
|
|
|
return EXIT_FAILURE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!std::filesystem::exists(BinaryPathFinder::GetBinaryDir() / "sharedconfig.ini")) {
|
|
|
|
|
Game::logger->Log("MasterServer", "Couldnt find sharedconfig.ini");
|
|
|
|
|
LOG("Couldnt find sharedconfig.ini");
|
|
|
|
|
return EXIT_FAILURE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!std::filesystem::exists(BinaryPathFinder::GetBinaryDir() / "worldconfig.ini")) {
|
|
|
|
|
Game::logger->Log("MasterServer", "Couldnt find worldconfig.ini");
|
|
|
|
|
LOG("Couldnt find worldconfig.ini");
|
|
|
|
|
return EXIT_FAILURE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -116,18 +116,18 @@ int main(int argc, char** argv) {
|
|
|
|
|
|
|
|
|
|
uint32_t clientNetVersion = 0;
|
|
|
|
|
if (!GeneralUtils::TryParse(Game::config->GetValue("client_net_version"), clientNetVersion)) {
|
|
|
|
|
Game::logger->Log("MasterServer", "Failed to parse (%s) as net version. Cannot start server as no clients could connect.", Game::config->GetValue("client_net_version").c_str());
|
|
|
|
|
Game::logger->Log("MasterServer", "As of version 1.1.1, client_net_version is required to be defined in sharedconfig.ini as opposed to in CMakeVariables.txt as NET_VERSION.");
|
|
|
|
|
Game::logger->Log("MasterServer", "Rerun cmake to ensure all config values exist. If client_net_version already exists in sharedconfig.ini, please ensure it is a valid number.");
|
|
|
|
|
Game::logger->Log("MasterServer", "like 171022");
|
|
|
|
|
LOG("Failed to parse (%s) as net version. Cannot start server as no clients could connect.",Game::config->GetValue("client_net_version").c_str());
|
|
|
|
|
LOG("As of version 1.1.1, client_net_version is required to be defined in sharedconfig.ini as opposed to in CMakeVariables.txt as NET_VERSION.");
|
|
|
|
|
LOG("Rerun cmake to ensure all config values exist. If client_net_version already exists in sharedconfig.ini, please ensure it is a valid number.");
|
|
|
|
|
LOG("like 171022");
|
|
|
|
|
return EXIT_FAILURE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Game::logger->Log("MasterServer", "Using net version %s", Game::config->GetValue("client_net_version").c_str());
|
|
|
|
|
LOG("Using net version %s", Game::config->GetValue("client_net_version").c_str());
|
|
|
|
|
|
|
|
|
|
Game::logger->Log("MasterServer", "Starting Master server...");
|
|
|
|
|
Game::logger->Log("MasterServer", "Version: %i.%i", PROJECT_VERSION_MAJOR, PROJECT_VERSION_MINOR);
|
|
|
|
|
Game::logger->Log("MasterServer", "Compiled on: %s", __TIMESTAMP__);
|
|
|
|
|
LOG("Starting Master server...");
|
|
|
|
|
LOG("Version: %i.%i", PROJECT_VERSION_MAJOR, PROJECT_VERSION_MINOR);
|
|
|
|
|
LOG("Compiled on: %s", __TIMESTAMP__);
|
|
|
|
|
|
|
|
|
|
//Connect to the MySQL Database
|
|
|
|
|
std::string mysql_host = Game::config->GetValue("mysql_host");
|
|
|
|
@@ -138,8 +138,8 @@ int main(int argc, char** argv) {
|
|
|
|
|
try {
|
|
|
|
|
Database::Connect(mysql_host, mysql_database, mysql_username, mysql_password);
|
|
|
|
|
} catch (sql::SQLException& ex) {
|
|
|
|
|
Game::logger->Log("MasterServer", "Got an error while connecting to the database: %s", ex.what());
|
|
|
|
|
Game::logger->Log("MigrationRunner", "Migrations not run");
|
|
|
|
|
LOG("Got an error while connecting to the database: %s", ex.what());
|
|
|
|
|
LOG("Migrations not run");
|
|
|
|
|
return EXIT_FAILURE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -153,7 +153,7 @@ int main(int argc, char** argv) {
|
|
|
|
|
|
|
|
|
|
Game::assetManager = new AssetManager(clientPath);
|
|
|
|
|
} catch (std::runtime_error& ex) {
|
|
|
|
|
Game::logger->Log("MasterServer", "Got an error while setting up assets: %s", ex.what());
|
|
|
|
|
LOG("Got an error while setting up assets: %s", ex.what());
|
|
|
|
|
|
|
|
|
|
return EXIT_FAILURE;
|
|
|
|
|
}
|
|
|
|
@@ -167,25 +167,24 @@ int main(int argc, char** argv) {
|
|
|
|
|
if (!cdServerExists) {
|
|
|
|
|
if (oldCDServerExists) {
|
|
|
|
|
// If the file doesn't exist in the new CDServer location, copy it there. We copy because we may not have write permissions from the previous directory.
|
|
|
|
|
Game::logger->Log("MasterServer", "CDServer.sqlite is not located at resServer, but is located at res path. Copying file...");
|
|
|
|
|
LOG("CDServer.sqlite is not located at resServer, but is located at res path. Copying file...");
|
|
|
|
|
std::filesystem::copy_file(Game::assetManager->GetResPath() / "CDServer.sqlite", BinaryPathFinder::GetBinaryDir() / "resServer" / "CDServer.sqlite");
|
|
|
|
|
} else {
|
|
|
|
|
Game::logger->Log("MasterServer",
|
|
|
|
|
"%s could not be found in resServer or res. Looking for %s to convert to sqlite.",
|
|
|
|
|
LOG("%s could not be found in resServer or res. Looking for %s to convert to sqlite.",
|
|
|
|
|
(BinaryPathFinder::GetBinaryDir() / "resServer" / "CDServer.sqlite").c_str(),
|
|
|
|
|
(Game::assetManager->GetResPath() / "cdclient.fdb").c_str());
|
|
|
|
|
|
|
|
|
|
AssetMemoryBuffer cdClientBuffer = Game::assetManager->GetFileAsBuffer("cdclient.fdb");
|
|
|
|
|
if (!cdClientBuffer.m_Success) {
|
|
|
|
|
Game::logger->Log("MasterServer", "Failed to load %s", (Game::assetManager->GetResPath() / "cdclient.fdb").c_str());
|
|
|
|
|
LOG("Failed to load %s", (Game::assetManager->GetResPath() / "cdclient.fdb").c_str());
|
|
|
|
|
throw std::runtime_error("Aborting initialization due to missing cdclient.fdb.");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Game::logger->Log("MasterServer", "Found %s. Converting to SQLite", (Game::assetManager->GetResPath() / "cdclient.fdb").c_str());
|
|
|
|
|
LOG("Found %s. Converting to SQLite", (Game::assetManager->GetResPath() / "cdclient.fdb").c_str());
|
|
|
|
|
Game::logger->Flush();
|
|
|
|
|
|
|
|
|
|
if (FdbToSqlite::Convert((BinaryPathFinder::GetBinaryDir() / "resServer").string()).ConvertDatabase(cdClientBuffer) == false) {
|
|
|
|
|
Game::logger->Log("MasterServer", "Failed to convert fdb to sqlite.");
|
|
|
|
|
LOG("Failed to convert fdb to sqlite.");
|
|
|
|
|
return EXIT_FAILURE;
|
|
|
|
|
}
|
|
|
|
|
cdClientBuffer.close();
|
|
|
|
@@ -196,9 +195,9 @@ int main(int argc, char** argv) {
|
|
|
|
|
try {
|
|
|
|
|
CDClientDatabase::Connect((BinaryPathFinder::GetBinaryDir() / "resServer" / "CDServer.sqlite").string());
|
|
|
|
|
} catch (CppSQLite3Exception& e) {
|
|
|
|
|
Game::logger->Log("WorldServer", "Unable to connect to CDServer SQLite Database");
|
|
|
|
|
Game::logger->Log("WorldServer", "Error: %s", e.errorMessage());
|
|
|
|
|
Game::logger->Log("WorldServer", "Error Code: %i", e.errorCode());
|
|
|
|
|
LOG("Unable to connect to CDServer SQLite Database");
|
|
|
|
|
LOG("Error: %s", e.errorMessage());
|
|
|
|
|
LOG("Error Code: %i", e.errorCode());
|
|
|
|
|
return EXIT_FAILURE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -209,10 +208,10 @@ int main(int argc, char** argv) {
|
|
|
|
|
try {
|
|
|
|
|
CDClientManager::Instance();
|
|
|
|
|
} catch (CppSQLite3Exception& e) {
|
|
|
|
|
Game::logger->Log("WorldServer", "Failed to initialize CDServer SQLite Database");
|
|
|
|
|
Game::logger->Log("WorldServer", "May be caused by corrupted file: %s", (Game::assetManager->GetResPath() / "CDServer.sqlite").string().c_str());
|
|
|
|
|
Game::logger->Log("WorldServer", "Error: %s", e.errorMessage());
|
|
|
|
|
Game::logger->Log("WorldServer", "Error Code: %i", e.errorCode());
|
|
|
|
|
LOG("Failed to initialize CDServer SQLite Database");
|
|
|
|
|
LOG("May be caused by corrupted file: %s", (Game::assetManager->GetResPath() / "CDServer.sqlite").string().c_str());
|
|
|
|
|
LOG("Error: %s", e.errorMessage());
|
|
|
|
|
LOG("Error Code: %i", e.errorCode());
|
|
|
|
|
return EXIT_FAILURE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -230,7 +229,7 @@ int main(int argc, char** argv) {
|
|
|
|
|
userLookupStatement->setString(1, username.c_str());
|
|
|
|
|
std::unique_ptr<sql::ResultSet> res(userLookupStatement->executeQuery());
|
|
|
|
|
if (res->rowsCount() > 0) {
|
|
|
|
|
Game::logger->Log("MasterServer", "Account with name \"%s\" already exists", username.c_str());
|
|
|
|
|
LOG("Account with name \"%s\" already exists", username.c_str());
|
|
|
|
|
std::cout << "Do you want to change the password of that account? [y/n]?";
|
|
|
|
|
std::string prompt = "";
|
|
|
|
|
std::cin >> prompt;
|
|
|
|
@@ -263,9 +262,9 @@ int main(int argc, char** argv) {
|
|
|
|
|
userUpdateStatement->setUInt(2, accountId);
|
|
|
|
|
userUpdateStatement->execute();
|
|
|
|
|
|
|
|
|
|
Game::logger->Log("MasterServer", "Account \"%s\" password updated successfully!", username.c_str());
|
|
|
|
|
LOG("Account \"%s\" password updated successfully!", username.c_str());
|
|
|
|
|
} else {
|
|
|
|
|
Game::logger->Log("MasterServer", "Account \"%s\" was not updated.", username.c_str());
|
|
|
|
|
LOG("Account \"%s\" was not updated.", username.c_str());
|
|
|
|
|
}
|
|
|
|
|
return EXIT_SUCCESS;
|
|
|
|
|
}
|
|
|
|
@@ -295,12 +294,12 @@ int main(int argc, char** argv) {
|
|
|
|
|
statement->setString(2, std::string(hash, BCRYPT_HASHSIZE).c_str());
|
|
|
|
|
statement->setInt(3, 9);
|
|
|
|
|
statement->execute();
|
|
|
|
|
} catch (sql::SQLException& e) {
|
|
|
|
|
Game::logger->Log("MasterServer", "A SQL error occurred!:\n %s", e.what());
|
|
|
|
|
} catch(sql::SQLException& e) {
|
|
|
|
|
LOG("A SQL error occurred!:\n %s", e.what());
|
|
|
|
|
return EXIT_FAILURE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Game::logger->Log("MasterServer", "Account created successfully!");
|
|
|
|
|
LOG("Account created successfully!");
|
|
|
|
|
return EXIT_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -450,7 +449,7 @@ int main(int argc, char** argv) {
|
|
|
|
|
return FinalizeShutdown(EXIT_SUCCESS);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
dLogger* SetupLogger() {
|
|
|
|
|
Logger* SetupLogger() {
|
|
|
|
|
std::string logPath =
|
|
|
|
|
(BinaryPathFinder::GetBinaryDir() / ("logs/MasterServer_" + std::to_string(time(nullptr)) + ".log")).string();
|
|
|
|
|
bool logToConsole = false;
|
|
|
|
@@ -460,19 +459,19 @@ dLogger* SetupLogger() {
|
|
|
|
|
logDebugStatements = true;
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
return new dLogger(logPath, logToConsole, logDebugStatements);
|
|
|
|
|
return new Logger(logPath, logToConsole, logDebugStatements);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void HandlePacket(Packet* packet) {
|
|
|
|
|
if (packet->data[0] == ID_DISCONNECTION_NOTIFICATION) {
|
|
|
|
|
Game::logger->Log("MasterServer", "A server has disconnected");
|
|
|
|
|
LOG("A server has disconnected");
|
|
|
|
|
|
|
|
|
|
//Since this disconnection is intentional, we'll just delete it as
|
|
|
|
|
//we'll start a new one anyway if needed:
|
|
|
|
|
Instance* instance =
|
|
|
|
|
Game::im->GetInstanceBySysAddr(packet->systemAddress);
|
|
|
|
|
if (instance) {
|
|
|
|
|
Game::logger->Log("MasterServer", "Actually disconnected from zone %i clone %i instance %i port %i", instance->GetMapID(), instance->GetCloneID(), instance->GetInstanceID(), instance->GetPort());
|
|
|
|
|
LOG("Actually disconnected from zone %i clone %i instance %i port %i", instance->GetMapID(), instance->GetCloneID(), instance->GetInstanceID(), instance->GetPort());
|
|
|
|
|
Game::im->RemoveInstance(instance); //Delete the old
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -488,7 +487,7 @@ void HandlePacket(Packet* packet) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (packet->data[0] == ID_CONNECTION_LOST) {
|
|
|
|
|
Game::logger->Log("MasterServer", "A server has lost the connection");
|
|
|
|
|
LOG("A server has lost the connection");
|
|
|
|
|
|
|
|
|
|
Instance* instance =
|
|
|
|
|
Game::im->GetInstanceBySysAddr(packet->systemAddress);
|
|
|
|
@@ -513,7 +512,7 @@ void HandlePacket(Packet* packet) {
|
|
|
|
|
if (static_cast<eConnectionType>(packet->data[1]) == eConnectionType::MASTER) {
|
|
|
|
|
switch (static_cast<eMasterMessageType>(packet->data[3])) {
|
|
|
|
|
case eMasterMessageType::REQUEST_PERSISTENT_ID: {
|
|
|
|
|
Game::logger->Log("MasterServer", "A persistent ID req");
|
|
|
|
|
LOG("A persistent ID req");
|
|
|
|
|
RakNet::BitStream inStream(packet->data, packet->length, false);
|
|
|
|
|
uint64_t header = inStream.Read(header);
|
|
|
|
|
uint64_t requestID = 0;
|
|
|
|
@@ -525,7 +524,7 @@ void HandlePacket(Packet* packet) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
case eMasterMessageType::REQUEST_ZONE_TRANSFER: {
|
|
|
|
|
Game::logger->Log("MasterServer", "Received zone transfer req");
|
|
|
|
|
LOG("Received zone transfer req");
|
|
|
|
|
RakNet::BitStream inStream(packet->data, packet->length, false);
|
|
|
|
|
uint64_t header = inStream.Read(header);
|
|
|
|
|
uint64_t requestID = 0;
|
|
|
|
@@ -538,24 +537,24 @@ void HandlePacket(Packet* packet) {
|
|
|
|
|
inStream.Read(zoneID);
|
|
|
|
|
inStream.Read(zoneClone);
|
|
|
|
|
if (shutdownSequenceStarted) {
|
|
|
|
|
Game::logger->Log("MasterServer", "Shutdown sequence has been started. Not creating a new zone.");
|
|
|
|
|
LOG("Shutdown sequence has been started. Not creating a new zone.");
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
Instance* in = Game::im->GetInstance(zoneID, false, zoneClone);
|
|
|
|
|
|
|
|
|
|
for (auto* instance : Game::im->GetInstances()) {
|
|
|
|
|
Game::logger->Log("MasterServer", "Instance: %i/%i/%i -> %i", instance->GetMapID(), instance->GetCloneID(), instance->GetInstanceID(), instance == in);
|
|
|
|
|
LOG("Instance: %i/%i/%i -> %i", instance->GetMapID(), instance->GetCloneID(), instance->GetInstanceID(), instance == in);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (in && !in->GetIsReady()) //Instance not ready, make a pending request
|
|
|
|
|
{
|
|
|
|
|
in->GetPendingRequests().push_back({ requestID, static_cast<bool>(mythranShift), packet->systemAddress });
|
|
|
|
|
Game::logger->Log("MasterServer", "Server not ready, adding pending request %llu %i %i", requestID, zoneID, zoneClone);
|
|
|
|
|
LOG("Server not ready, adding pending request %llu %i %i", requestID, zoneID, zoneClone);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//Instance is ready, transfer
|
|
|
|
|
Game::logger->Log("MasterServer", "Responding to transfer request %llu for zone %i %i", requestID, zoneID, zoneClone);
|
|
|
|
|
LOG("Responding to transfer request %llu for zone %i %i", requestID, zoneID, zoneClone);
|
|
|
|
|
Game::im->RequestAffirmation(in, { requestID, static_cast<bool>(mythranShift), packet->systemAddress });
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
@@ -616,7 +615,7 @@ void HandlePacket(Packet* packet) {
|
|
|
|
|
authServerMasterPeerSysAddr = copy;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Game::logger->Log("MasterServer", "Received server info, instance: %i port: %i", theirInstanceID, theirPort);
|
|
|
|
|
LOG("Received server info, instance: %i port: %i", theirInstanceID, theirPort);
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
@@ -648,7 +647,7 @@ void HandlePacket(Packet* packet) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
activeSessions.insert(std::make_pair(sessionKey, username));
|
|
|
|
|
Game::logger->Log("MasterServer", "Got sessionKey %i for user %s", sessionKey, username.c_str());
|
|
|
|
|
LOG("Got sessionKey %i for user %s", sessionKey, username.c_str());
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -754,7 +753,7 @@ void HandlePacket(Packet* packet) {
|
|
|
|
|
|
|
|
|
|
auto* instance = Game::im->FindPrivateInstance(password.c_str());
|
|
|
|
|
|
|
|
|
|
Game::logger->Log("MasterServer", "Join private zone: %llu %d %s %p", requestID, mythranShift, password.c_str(), instance);
|
|
|
|
|
LOG("Join private zone: %llu %d %s %p", requestID, mythranShift, password.c_str(), instance);
|
|
|
|
|
|
|
|
|
|
if (instance == nullptr) {
|
|
|
|
|
return;
|
|
|
|
@@ -777,16 +776,16 @@ void HandlePacket(Packet* packet) {
|
|
|
|
|
inStream.Read(zoneID);
|
|
|
|
|
inStream.Read(instanceID);
|
|
|
|
|
|
|
|
|
|
Game::logger->Log("MasterServer", "Got world ready %i %i", zoneID, instanceID);
|
|
|
|
|
LOG("Got world ready %i %i", zoneID, instanceID);
|
|
|
|
|
|
|
|
|
|
auto* instance = Game::im->FindInstance(zoneID, instanceID);
|
|
|
|
|
|
|
|
|
|
if (instance == nullptr) {
|
|
|
|
|
Game::logger->Log("MasterServer", "Failed to find zone to ready");
|
|
|
|
|
LOG("Failed to find zone to ready");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Game::logger->Log("MasterServer", "Ready zone %i", zoneID);
|
|
|
|
|
LOG("Ready zone %i", zoneID);
|
|
|
|
|
Game::im->ReadyInstance(instance);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
@@ -798,10 +797,10 @@ void HandlePacket(Packet* packet) {
|
|
|
|
|
int32_t zoneID;
|
|
|
|
|
inStream.Read(zoneID);
|
|
|
|
|
if (shutdownSequenceStarted) {
|
|
|
|
|
Game::logger->Log("MasterServer", "Shutdown sequence has been started. Not prepping a new zone.");
|
|
|
|
|
LOG("Shutdown sequence has been started. Not prepping a new zone.");
|
|
|
|
|
break;
|
|
|
|
|
} else {
|
|
|
|
|
Game::logger->Log("MasterServer", "Prepping zone %i", zoneID);
|
|
|
|
|
LOG("Prepping zone %i", zoneID);
|
|
|
|
|
Game::im->GetInstance(zoneID, false, 0);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
@@ -815,7 +814,7 @@ void HandlePacket(Packet* packet) {
|
|
|
|
|
|
|
|
|
|
inStream.Read(requestID);
|
|
|
|
|
|
|
|
|
|
Game::logger->Log("MasterServer", "Got affirmation of transfer %llu", requestID);
|
|
|
|
|
LOG("Got affirmation of transfer %llu", requestID);
|
|
|
|
|
|
|
|
|
|
auto* instance = Game::im->GetInstanceBySysAddr(packet->systemAddress);
|
|
|
|
|
|
|
|
|
@@ -823,7 +822,7 @@ void HandlePacket(Packet* packet) {
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
Game::im->AffirmTransfer(instance, requestID);
|
|
|
|
|
Game::logger->Log("MasterServer", "Affirmation complete %llu", requestID);
|
|
|
|
|
LOG("Affirmation complete %llu", requestID);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -837,26 +836,26 @@ void HandlePacket(Packet* packet) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Game::logger->Log("MasterServer", "Got shutdown response from zone %i clone %i instance %i port %i", instance->GetMapID(), instance->GetCloneID(), instance->GetInstanceID(), instance->GetPort());
|
|
|
|
|
LOG("Got shutdown response from zone %i clone %i instance %i port %i", instance->GetMapID(), instance->GetCloneID(), instance->GetInstanceID(), instance->GetPort());
|
|
|
|
|
instance->SetIsShuttingDown(true);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
case eMasterMessageType::SHUTDOWN_UNIVERSE: {
|
|
|
|
|
Game::logger->Log("MasterServer", "Received shutdown universe command, shutting down in 10 minutes.");
|
|
|
|
|
LOG("Received shutdown universe command, shutting down in 10 minutes.");
|
|
|
|
|
Game::shouldShutdown = true;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
Game::logger->Log("MasterServer", "Unknown master packet ID from server: %i", packet->data[3]);
|
|
|
|
|
LOG("Unknown master packet ID from server: %i", packet->data[3]);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void StartChatServer() {
|
|
|
|
|
if (Game::shouldShutdown) {
|
|
|
|
|
Game::logger->Log("MasterServer", "Currently shutting down. Chat will not be restarted.");
|
|
|
|
|
LOG("Currently shutting down. Chat will not be restarted.");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
#ifdef __APPLE__
|
|
|
|
@@ -875,7 +874,7 @@ void StartChatServer() {
|
|
|
|
|
|
|
|
|
|
void StartAuthServer() {
|
|
|
|
|
if (Game::shouldShutdown) {
|
|
|
|
|
Game::logger->Log("MasterServer", "Currently shutting down. Auth will not be restarted.");
|
|
|
|
|
LOG("Currently shutting down. Auth will not be restarted.");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
#ifdef __APPLE__
|
|
|
|
@@ -908,13 +907,13 @@ void ShutdownSequence(int32_t signal) {
|
|
|
|
|
CBITSTREAM;
|
|
|
|
|
BitStreamUtils::WriteHeader(bitStream, eConnectionType::MASTER, eMasterMessageType::SHUTDOWN);
|
|
|
|
|
Game::server->Send(&bitStream, UNASSIGNED_SYSTEM_ADDRESS, true);
|
|
|
|
|
Game::logger->Log("MasterServer", "Triggered master shutdown");
|
|
|
|
|
LOG("Triggered master shutdown");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
auto* objIdManager = ObjectIDManager::TryInstance();
|
|
|
|
|
if (objIdManager) {
|
|
|
|
|
objIdManager->SaveToDatabase();
|
|
|
|
|
Game::logger->Log("MasterServer", "Saved ObjectIDTracker to DB");
|
|
|
|
|
LOG("Saved ObjectIDTracker to DB");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// A server might not be finished spinning up yet, remove all of those here.
|
|
|
|
@@ -928,7 +927,7 @@ void ShutdownSequence(int32_t signal) {
|
|
|
|
|
instance->SetIsShuttingDown(true);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Game::logger->Log("MasterServer", "Attempting to shutdown instances, max 60 seconds...");
|
|
|
|
|
LOG("Attempting to shutdown instances, max 60 seconds...");
|
|
|
|
|
|
|
|
|
|
auto t = std::chrono::high_resolution_clock::now();
|
|
|
|
|
uint32_t framesSinceShutdownStart = 0;
|
|
|
|
@@ -956,7 +955,7 @@ void ShutdownSequence(int32_t signal) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (allInstancesShutdown && authServerMasterPeerSysAddr == UNASSIGNED_SYSTEM_ADDRESS && chatServerMasterPeerSysAddr == UNASSIGNED_SYSTEM_ADDRESS) {
|
|
|
|
|
Game::logger->Log("MasterServer", "Finished shutting down MasterServer!");
|
|
|
|
|
LOG("Finished shutting down MasterServer!");
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -966,7 +965,7 @@ void ShutdownSequence(int32_t signal) {
|
|
|
|
|
framesSinceShutdownStart++;
|
|
|
|
|
|
|
|
|
|
if (framesSinceShutdownStart == maxShutdownTime) {
|
|
|
|
|
Game::logger->Log("MasterServer", "Finished shutting down by timeout!");
|
|
|
|
|
LOG("Finished shutting down by timeout!");
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|