Merge branch 'MoreImprovements' of https://github.com/EmosewaMC/DarkflameServer into MoreImprovements

This commit is contained in:
David Markowitz 2022-12-16 01:28:52 -08:00
commit e78dc0b874
9 changed files with 95 additions and 66 deletions

View File

@ -138,7 +138,7 @@ int main(int argc, char** argv) {
} else framesSinceLastSQLPing++; } else framesSinceLastSQLPing++;
//Sleep our thread since auth can afford to. //Sleep our thread since auth can afford to.
t += std::chrono::milliseconds(mediumFramerate); //Auth can run at a lower "fps" t += std::chrono::milliseconds(mediumFrameDelta); //Auth can run at a lower "fps"
std::this_thread::sleep_until(t); std::this_thread::sleep_until(t);
} }

View File

@ -160,7 +160,7 @@ int main(int argc, char** argv) {
} else framesSinceLastSQLPing++; } else framesSinceLastSQLPing++;
//Sleep our thread since auth can afford to. //Sleep our thread since auth can afford to.
t += std::chrono::milliseconds(mediumFramerate); //Chat can run at a lower "fps" t += std::chrono::milliseconds(mediumFrameDelta); //Chat can run at a lower "fps"
std::this_thread::sleep_until(t); std::this_thread::sleep_until(t);
} }

View File

@ -6,15 +6,22 @@
#include <cstdint> #include <cstdint>
#include <string> #include <string>
#include <set> #include <set>
#include "../thirdparty/raknet/Source/BitStream.h" #include "BitStream.h"
#pragma warning (disable:4251) //Disables SQL warnings #pragma warning (disable:4251) //Disables SQL warnings
typedef int RESTICKET; typedef int RESTICKET;
const int highFrameRate = 16; //60fps #define FRAMES_TO_MS(x) 1000 / x
const int mediumFramerate = 33; //30fps
const int lowFramerate = 66; //15fps //=========== FRAME TIMINGS ===========
constexpr uint32_t highFramerate = 60;
constexpr uint32_t mediumFramerate = 30;
constexpr uint32_t lowFramerate = 15;
constexpr uint32_t highFrameDelta = FRAMES_TO_MS(highFramerate);
constexpr uint32_t mediumFrameDelta = FRAMES_TO_MS(mediumFramerate);
constexpr uint32_t lowFrameDelta = FRAMES_TO_MS(lowFramerate);
//========== MACROS =========== //========== MACROS ===========

View File

@ -31,6 +31,15 @@ Instance* InstanceManager::GetInstance(LWOMAPID mapID, bool isFriendTransfer, LW
Instance* instance = FindInstance(mapID, isFriendTransfer, cloneID); Instance* instance = FindInstance(mapID, isFriendTransfer, cloneID);
if (instance) return instance; if (instance) return instance;
// If we are shutting down, return a nullptr so a new instance is not created.
if (m_IsShuttingDown) {
Game::logger->Log("InstanceManager",
"Tried to create a new instance map/instance/clone %i/%i/%i, but Master is shutting down.",
mapID,
m_LastInstanceID + 1,
cloneID);
return nullptr;
}
//TODO: Update this so that the IP is read from a configuration file instead //TODO: Update this so that the IP is read from a configuration file instead
int softCap = 8; int softCap = 8;
@ -238,7 +247,7 @@ void InstanceManager::RedirectPendingRequests(Instance* instance) {
for (const auto& request : instance->GetPendingAffirmations()) { for (const auto& request : instance->GetPendingAffirmations()) {
auto* in = Game::im->GetInstance(zoneId.GetMapID(), false, zoneId.GetCloneID()); auto* in = Game::im->GetInstance(zoneId.GetMapID(), false, zoneId.GetCloneID());
if (!in->GetIsReady()) // Instance not ready, make a pending request if (in && !in->GetIsReady()) // Instance not ready, make a pending request
{ {
in->GetPendingRequests().push_back(request); in->GetPendingRequests().push_back(request);
@ -295,6 +304,15 @@ Instance* InstanceManager::CreatePrivateInstance(LWOMAPID mapID, LWOCLONEID clon
return instance; return instance;
} }
if (m_IsShuttingDown) {
Game::logger->Log("InstanceManager",
"Tried to create a new private instance map/instance/clone %i/%i/%i, but Master is shutting down.",
mapID,
m_LastInstanceID + 1,
cloneID);
return nullptr;
}
int maxPlayers = 999; int maxPlayers = 999;
uint32_t port = GetFreePort(); uint32_t port = GetFreePort();

View File

@ -128,6 +128,7 @@ public:
Instance* CreatePrivateInstance(LWOMAPID mapID, LWOCLONEID cloneID, const std::string& password); Instance* CreatePrivateInstance(LWOMAPID mapID, LWOCLONEID cloneID, const std::string& password);
Instance* FindPrivateInstance(const std::string& password); Instance* FindPrivateInstance(const std::string& password);
void SetIsShuttingDown(bool value) { this->m_IsShuttingDown = value; };
private: private:
dLogger* mLogger; dLogger* mLogger;
@ -136,6 +137,11 @@ private:
unsigned short m_LastPort; unsigned short m_LastPort;
LWOINSTANCEID m_LastInstanceID; LWOINSTANCEID m_LastInstanceID;
/**
* Whether or not the master server is currently shutting down.
*/
bool m_IsShuttingDown = false;
//Private functions: //Private functions:
bool IsInstanceFull(Instance* instance, bool isFriendTransfer); bool IsInstanceFull(Instance* instance, bool isFriendTransfer);
int GetSoftCap(LWOMAPID mapID); int GetSoftCap(LWOMAPID mapID);

View File

@ -63,6 +63,8 @@ SystemAddress authServerMasterPeerSysAddr;
SystemAddress chatServerMasterPeerSysAddr; SystemAddress chatServerMasterPeerSysAddr;
int main(int argc, char** argv) { int main(int argc, char** argv) {
constexpr uint32_t masterFramerate = mediumFramerate;
constexpr uint32_t masterFrameDelta = mediumFrameDelta;
Diagnostics::SetProcessName("Master"); Diagnostics::SetProcessName("Master");
Diagnostics::SetProcessFileName(argv[0]); Diagnostics::SetProcessFileName(argv[0]);
Diagnostics::Initialize(); Diagnostics::Initialize();
@ -287,6 +289,10 @@ int main(int argc, char** argv) {
auto t = std::chrono::high_resolution_clock::now(); auto t = std::chrono::high_resolution_clock::now();
Packet* packet = nullptr; Packet* packet = nullptr;
constexpr uint32_t logFlushTime = 15 * masterFramerate;
constexpr uint32_t sqlPingTime = 10 * 60 * masterFramerate;
constexpr uint32_t shutdownUniverseTime = 10 * 60 * masterFramerate;
constexpr uint32_t instanceReadyTimeout = 30 * masterFramerate;
int framesSinceLastFlush = 0; int framesSinceLastFlush = 0;
int framesSinceLastSQLPing = 0; int framesSinceLastSQLPing = 0;
int framesSinceKillUniverseCommand = 0; int framesSinceKillUniverseCommand = 0;
@ -303,14 +309,14 @@ int main(int argc, char** argv) {
} }
//Push our log every 15s: //Push our log every 15s:
if (framesSinceLastFlush >= 900) { if (framesSinceLastFlush >= logFlushTime) {
Game::logger->Flush(); Game::logger->Flush();
framesSinceLastFlush = 0; framesSinceLastFlush = 0;
} else } else
framesSinceLastFlush++; framesSinceLastFlush++;
//Every 10 min we ping our sql server to keep it alive hopefully: //Every 10 min we ping our sql server to keep it alive hopefully:
if (framesSinceLastSQLPing >= 40000) { if (framesSinceLastSQLPing >= sqlPingTime) {
//Find out the master's IP for absolutely no reason: //Find out the master's IP for absolutely no reason:
std::string masterIP; std::string masterIP;
int masterPort; int masterPort;
@ -330,7 +336,7 @@ int main(int argc, char** argv) {
//10m shutdown for universe kill command //10m shutdown for universe kill command
if (Game::shouldShutdown) { if (Game::shouldShutdown) {
if (framesSinceKillUniverseCommand >= 40000) { if (framesSinceKillUniverseCommand >= shutdownUniverseTime) {
//Break main loop and exit //Break main loop and exit
break; break;
} else } else
@ -354,7 +360,7 @@ int main(int argc, char** argv) {
instance->SetAffirmationTimeout(affirmTimeout); instance->SetAffirmationTimeout(affirmTimeout);
if (affirmTimeout == 1000) { if (affirmTimeout == instanceReadyTimeout) {
instance->Shutdown(); instance->Shutdown();
instance->SetIsShuttingDown(true); instance->SetIsShuttingDown(true);
@ -373,7 +379,7 @@ int main(int argc, char** argv) {
} }
} }
t += std::chrono::milliseconds(highFrameRate); t += std::chrono::milliseconds(masterFrameDelta);
std::this_thread::sleep_until(t); std::this_thread::sleep_until(t);
} }
return FinalizeShutdown(EXIT_SUCCESS); return FinalizeShutdown(EXIT_SUCCESS);
@ -424,7 +430,6 @@ void HandlePacket(Packet* packet) {
if (instance) { if (instance) {
LWOZONEID zoneID = instance->GetZoneID(); //Get the zoneID so we can recreate a server LWOZONEID zoneID = instance->GetZoneID(); //Get the zoneID so we can recreate a server
Game::im->RemoveInstance(instance); //Delete the old Game::im->RemoveInstance(instance); //Delete the old
//Game::im->GetInstance(zoneID.GetMapID(), false, 0); //Create the new
} }
if (packet->systemAddress == chatServerMasterPeerSysAddr) { if (packet->systemAddress == chatServerMasterPeerSysAddr) {
@ -465,14 +470,17 @@ void HandlePacket(Packet* packet) {
inStream.Read(mythranShift); inStream.Read(mythranShift);
inStream.Read(zoneID); inStream.Read(zoneID);
inStream.Read(zoneClone); inStream.Read(zoneClone);
if (shutdownSequenceStarted) {
Game::logger->Log("MasterServer", "Shutdown sequence has been started. Not creating a new zone.");
break;
}
Instance* in = Game::im->GetInstance(zoneID, false, zoneClone); Instance* in = Game::im->GetInstance(zoneID, false, zoneClone);
for (auto* instance : Game::im->GetInstances()) { for (auto* instance : Game::im->GetInstances()) {
Game::logger->Log("MasterServer", "Instance: %i/%i/%i -> %i", instance->GetMapID(), instance->GetCloneID(), instance->GetInstanceID(), instance == in); Game::logger->Log("MasterServer", "Instance: %i/%i/%i -> %i", instance->GetMapID(), instance->GetCloneID(), instance->GetInstanceID(), instance == in);
} }
if (!in->GetIsReady()) //Instance not ready, make a pending request if (in && !in->GetIsReady()) //Instance not ready, make a pending request
{ {
in->GetPendingRequests().push_back({ requestID, static_cast<bool>(mythranShift), packet->systemAddress }); 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); Game::logger->Log("MasterServer", "Server not ready, adding pending request %llu %i %i", requestID, zoneID, zoneClone);
@ -720,9 +728,13 @@ void HandlePacket(Packet* packet) {
int zoneID; int zoneID;
inStream.Read(zoneID); inStream.Read(zoneID);
if (shutdownSequenceStarted) {
Game::logger->Log("MasterServer", "Prepping zone %i", zoneID); Game::logger->Log("MasterServer", "Shutdown sequence has been started. Not prepping a new zone.");
Game::im->GetInstance(zoneID, false, 0); break;
} else {
Game::logger->Log("MasterServer", "Prepping zone %i", zoneID);
Game::im->GetInstance(zoneID, false, 0);
}
break; break;
} }
@ -770,8 +782,8 @@ 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) { if (Game::shouldShutdown) {
@ -788,9 +800,9 @@ void StartChatServer() {
auto result = system(("sudo " + (BinaryPathFinder::GetBinaryDir() / "ChatServer").string() + "&").c_str()); auto result = system(("sudo " + (BinaryPathFinder::GetBinaryDir() / "ChatServer").string() + "&").c_str());
} else { } else {
auto result = system(((BinaryPathFinder::GetBinaryDir() / "ChatServer").string() + "&").c_str()); auto result = system(((BinaryPathFinder::GetBinaryDir() / "ChatServer").string() + "&").c_str());
} }
#endif #endif
} }
void StartAuthServer() { void StartAuthServer() {
if (Game::shouldShutdown) { if (Game::shouldShutdown) {
@ -806,7 +818,7 @@ void StartAuthServer() {
auto result = system(("sudo " + (BinaryPathFinder::GetBinaryDir() / "AuthServer").string() + "&").c_str()); auto result = system(("sudo " + (BinaryPathFinder::GetBinaryDir() / "AuthServer").string() + "&").c_str());
} else { } else {
auto result = system(((BinaryPathFinder::GetBinaryDir() / "AuthServer").string() + "&").c_str()); auto result = system(((BinaryPathFinder::GetBinaryDir() / "AuthServer").string() + "&").c_str());
} }
#endif #endif
} }
@ -815,6 +827,11 @@ void ShutdownSequence(int signal) {
return; return;
} }
if (!Game::im) {
FinalizeShutdown(EXIT_FAILURE);
}
Game::im->SetIsShuttingDown(true);
shutdownSequenceStarted = true; shutdownSequenceStarted = true;
Game::shouldShutdown = true; Game::shouldShutdown = true;
@ -826,40 +843,38 @@ void ShutdownSequence(int signal) {
} }
auto* objIdManager = ObjectIDManager::TryInstance(); auto* objIdManager = ObjectIDManager::TryInstance();
if (objIdManager != nullptr) { if (objIdManager) {
objIdManager->SaveToDatabase(); objIdManager->SaveToDatabase();
Game::logger->Log("MasterServer", "Saved ObjectIDTracker to DB"); Game::logger->Log("MasterServer", "Saved ObjectIDTracker to DB");
} }
auto t = std::chrono::high_resolution_clock::now();
auto ticks = 0;
if (!Game::im) {
FinalizeShutdown(EXIT_FAILURE);
}
// A server might not be finished spinning up yet, remove all of those here. // A server might not be finished spinning up yet, remove all of those here.
for (auto instance : Game::im->GetInstances()) { for (auto* instance : Game::im->GetInstances()) {
if (!instance->GetIsReady()) { if (!instance->GetIsReady()) {
Game::im->RemoveInstance(instance); Game::im->RemoveInstance(instance);
} }
} }
for (auto instance : Game::im->GetInstances()) { for (auto* instance : Game::im->GetInstances()) {
instance->SetIsShuttingDown(true); instance->SetIsShuttingDown(true);
} }
Game::logger->Log("MasterServer", "Attempting to shutdown instances, max 60 seconds..."); Game::logger->Log("MasterServer", "Attempting to shutdown instances, max 60 seconds...");
auto t = std::chrono::high_resolution_clock::now();
uint32_t framesSinceShutdownStart = 0;
constexpr uint32_t maxShutdownTime = 60 * mediumFramerate;
bool allInstancesShutdown = false;
Packet* packet = nullptr;
while (true) { while (true) {
auto packet = Game::server->Receive(); packet = Game::server->Receive();
if (packet) { if (packet) {
HandlePacket(packet); HandlePacket(packet);
Game::server->DeallocatePacket(packet); Game::server->DeallocatePacket(packet);
packet = nullptr; packet = nullptr;
} }
auto done = true; allInstancesShutdown = true;
for (auto* instance : Game::im->GetInstances()) { for (auto* instance : Game::im->GetInstances()) {
if (instance == nullptr) { if (instance == nullptr) {
@ -867,21 +882,21 @@ void ShutdownSequence(int signal) {
} }
if (!instance->GetShutdownComplete()) { if (!instance->GetShutdownComplete()) {
done = false; allInstancesShutdown = false;
} }
} }
if (done && authServerMasterPeerSysAddr == UNASSIGNED_SYSTEM_ADDRESS && chatServerMasterPeerSysAddr == UNASSIGNED_SYSTEM_ADDRESS) { if (allInstancesShutdown && 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;
} }
t += std::chrono::milliseconds(highFrameRate); t += std::chrono::milliseconds(mediumFrameDelta);
std::this_thread::sleep_until(t); std::this_thread::sleep_until(t);
ticks++; framesSinceShutdownStart++;
if (ticks == 600 * 6) { if (framesSinceShutdownStart == maxShutdownTime) {
Game::logger->Log("MasterServer", "Finished shutting down by timeout!"); Game::logger->Log("MasterServer", "Finished shutting down by timeout!");
break; break;
} }

View File

@ -2,23 +2,18 @@
#include "UserManager.h" #include "UserManager.h"
//Times are 1 / fps, in ms #define SOCIAL { lowFrameDelta }
#define HIGH 16 //60 fps #define SOCIAL_HUB { mediumFrameDelta } //Added to compensate for the large playercounts in NS and NT
#define MEDIUM 33 //30 fps #define BATTLE { highFrameDelta }
#define LOW 66 //15 fps #define BATTLE_INSTANCE { mediumFrameDelta }
#define RACE { highFrameDelta }
#define SOCIAL { LOW } #define PROPERTY { lowFrameDelta }
#define SOCIAL_HUB { MEDIUM } //Added to compensate for the large playercounts in NS and NT
#define BATTLE { HIGH }
#define BATTLE_INSTANCE { MEDIUM }
#define RACE { HIGH }
#define PROPERTY { LOW }
PerformanceProfile PerformanceManager::m_CurrentProfile = SOCIAL; PerformanceProfile PerformanceManager::m_CurrentProfile = SOCIAL;
PerformanceProfile PerformanceManager::m_DefaultProfile = SOCIAL; PerformanceProfile PerformanceManager::m_DefaultProfile = SOCIAL;
PerformanceProfile PerformanceManager::m_InactiveProfile = { LOW }; PerformanceProfile PerformanceManager::m_InactiveProfile = { lowFrameDelta };
std::map<LWOMAPID, PerformanceProfile> PerformanceManager::m_Profiles = { std::map<LWOMAPID, PerformanceProfile> PerformanceManager::m_Profiles = {
// VE // VE
@ -72,13 +67,6 @@ std::map<LWOMAPID, PerformanceProfile> PerformanceManager::m_Profiles = {
{ 2001, BATTLE_INSTANCE }, { 2001, BATTLE_INSTANCE },
}; };
PerformanceManager::PerformanceManager() {
}
PerformanceManager::~PerformanceManager() {
}
void PerformanceManager::SelectProfile(LWOMAPID mapID) { void PerformanceManager::SelectProfile(LWOMAPID mapID) {
const auto pair = m_Profiles.find(mapID); const auto pair = m_Profiles.find(mapID);

View File

@ -8,18 +8,13 @@ struct PerformanceProfile {
uint32_t serverFramerate; uint32_t serverFramerate;
}; };
class PerformanceManager { class PerformanceManager {
public: public:
~PerformanceManager();
static void SelectProfile(LWOMAPID mapID); static void SelectProfile(LWOMAPID mapID);
static uint32_t GetServerFramerate(); static uint32_t GetServerFramerate();
private: private:
PerformanceManager();
static PerformanceProfile m_CurrentProfile; static PerformanceProfile m_CurrentProfile;
static PerformanceProfile m_DefaultProfile; static PerformanceProfile m_DefaultProfile;
static PerformanceProfile m_InactiveProfile; static PerformanceProfile m_InactiveProfile;

View File

@ -232,7 +232,7 @@ int main(int argc, char** argv) {
bool ready = false; bool ready = false;
int framesSinceMasterStatus = 0; int framesSinceMasterStatus = 0;
int framesSinceShutdownSequence = 0; int framesSinceShutdownSequence = 0;
int currentFramerate = highFrameRate; int currentFramerate = highFrameDelta;
int ghostingStepCount = 0; int ghostingStepCount = 0;
auto ghostingLastTime = std::chrono::high_resolution_clock::now(); auto ghostingLastTime = std::chrono::high_resolution_clock::now();
@ -300,7 +300,7 @@ int main(int argc, char** argv) {
const auto occupied = UserManager::Instance()->GetUserCount() != 0; const auto occupied = UserManager::Instance()->GetUserCount() != 0;
if (!ready) { if (!ready) {
currentFramerate = highFrameRate; currentFramerate = highFrameDelta;
} else { } else {
currentFramerate = PerformanceManager::GetServerFramerate(); currentFramerate = PerformanceManager::GetServerFramerate();
} }