mirror of
https://github.com/DarkflameUniverse/DarkflameServer.git
synced 2025-08-04 09:44:10 +00:00
Merge pull request #889 from EmosewaMC/MoreImprovements
Continued improvements to Servers
This commit is contained in:
@@ -2,23 +2,18 @@
|
||||
|
||||
#include "UserManager.h"
|
||||
|
||||
//Times are 1 / fps, in ms
|
||||
#define HIGH 16 //60 fps
|
||||
#define MEDIUM 33 //30 fps
|
||||
#define LOW 66 //15 fps
|
||||
|
||||
#define SOCIAL { LOW }
|
||||
#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 }
|
||||
#define SOCIAL { lowFrameDelta }
|
||||
#define SOCIAL_HUB { mediumFrameDelta } //Added to compensate for the large playercounts in NS and NT
|
||||
#define BATTLE { highFrameDelta }
|
||||
#define BATTLE_INSTANCE { mediumFrameDelta }
|
||||
#define RACE { highFrameDelta }
|
||||
#define PROPERTY { lowFrameDelta }
|
||||
|
||||
PerformanceProfile PerformanceManager::m_CurrentProfile = SOCIAL;
|
||||
|
||||
PerformanceProfile PerformanceManager::m_DefaultProfile = SOCIAL;
|
||||
|
||||
PerformanceProfile PerformanceManager::m_InactiveProfile = { LOW };
|
||||
PerformanceProfile PerformanceManager::m_InactiveProfile = { lowFrameDelta };
|
||||
|
||||
std::map<LWOMAPID, PerformanceProfile> PerformanceManager::m_Profiles = {
|
||||
// VE
|
||||
@@ -72,13 +67,6 @@ std::map<LWOMAPID, PerformanceProfile> PerformanceManager::m_Profiles = {
|
||||
{ 2001, BATTLE_INSTANCE },
|
||||
};
|
||||
|
||||
|
||||
PerformanceManager::PerformanceManager() {
|
||||
}
|
||||
|
||||
PerformanceManager::~PerformanceManager() {
|
||||
}
|
||||
|
||||
void PerformanceManager::SelectProfile(LWOMAPID mapID) {
|
||||
const auto pair = m_Profiles.find(mapID);
|
||||
|
||||
@@ -91,10 +79,10 @@ void PerformanceManager::SelectProfile(LWOMAPID mapID) {
|
||||
m_CurrentProfile = pair->second;
|
||||
}
|
||||
|
||||
uint32_t PerformanceManager::GetServerFramerate() {
|
||||
uint32_t PerformanceManager::GetServerFrameDelta() {
|
||||
if (UserManager::Instance()->GetUserCount() == 0) {
|
||||
return m_InactiveProfile.serverFramerate;
|
||||
return m_InactiveProfile.serverFrameDelta;
|
||||
}
|
||||
|
||||
return m_CurrentProfile.serverFramerate;
|
||||
return m_CurrentProfile.serverFrameDelta;
|
||||
}
|
||||
|
@@ -5,21 +5,16 @@
|
||||
#include "dCommonVars.h"
|
||||
|
||||
struct PerformanceProfile {
|
||||
uint32_t serverFramerate;
|
||||
uint32_t serverFrameDelta;
|
||||
};
|
||||
|
||||
|
||||
class PerformanceManager {
|
||||
public:
|
||||
~PerformanceManager();
|
||||
|
||||
static void SelectProfile(LWOMAPID mapID);
|
||||
|
||||
static uint32_t GetServerFramerate();
|
||||
static uint32_t GetServerFrameDelta();
|
||||
|
||||
private:
|
||||
PerformanceManager();
|
||||
|
||||
static PerformanceProfile m_CurrentProfile;
|
||||
static PerformanceProfile m_DefaultProfile;
|
||||
static PerformanceProfile m_InactiveProfile;
|
||||
|
@@ -82,7 +82,7 @@ void WorldShutdownProcess(uint32_t zoneId);
|
||||
void FinalizeShutdown();
|
||||
void SendShutdownMessageToMaster();
|
||||
|
||||
dLogger* SetupLogger(int zoneID, int instanceID);
|
||||
dLogger* SetupLogger(uint32_t zoneID, uint32_t instanceID);
|
||||
void HandlePacketChat(Packet* packet);
|
||||
void HandlePacket(Packet* packet);
|
||||
|
||||
@@ -92,8 +92,8 @@ struct tempSessionInfo {
|
||||
};
|
||||
|
||||
std::map<std::string, tempSessionInfo> m_PendingUsers;
|
||||
int instanceID = 0;
|
||||
int g_CloneID = 0;
|
||||
uint32_t instanceID = 0;
|
||||
uint32_t g_CloneID = 0;
|
||||
std::string databaseChecksum = "";
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
@@ -107,13 +107,13 @@ int main(int argc, char** argv) {
|
||||
signal(SIGINT, [](int) { WorldShutdownSequence(); });
|
||||
signal(SIGTERM, [](int) { WorldShutdownSequence(); });
|
||||
|
||||
int zoneID = 1000;
|
||||
int cloneID = 0;
|
||||
int maxClients = 8;
|
||||
int ourPort = 2007;
|
||||
uint32_t zoneID = 1000;
|
||||
uint32_t cloneID = 0;
|
||||
uint32_t maxClients = 8;
|
||||
uint32_t ourPort = 2007;
|
||||
|
||||
//Check our arguments:
|
||||
for (int i = 0; i < argc; ++i) {
|
||||
for (int32_t i = 0; i < argc; ++i) {
|
||||
std::string argument(argv[i]);
|
||||
|
||||
if (argument == "-zone") zoneID = atoi(argv[i + 1]);
|
||||
@@ -185,7 +185,7 @@ int main(int argc, char** argv) {
|
||||
|
||||
//Find out the master's IP:
|
||||
std::string masterIP = "localhost";
|
||||
int masterPort = 1000;
|
||||
uint32_t masterPort = 1000;
|
||||
sql::PreparedStatement* stmt = Database::CreatePreppedStmt("SELECT ip, port FROM servers WHERE name='master';");
|
||||
auto res = stmt->executeQuery();
|
||||
while (res->next()) {
|
||||
@@ -204,7 +204,7 @@ int main(int argc, char** argv) {
|
||||
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:
|
||||
int chatPort = 1501;
|
||||
uint32_t chatPort = 1501;
|
||||
if (Game::config->GetValue("chat_server_port") != "") chatPort = std::atoi(Game::config->GetValue("chat_server_port").c_str());
|
||||
|
||||
auto chatSock = SocketDescriptor(uint16_t(ourPort + 2), 0);
|
||||
@@ -220,22 +220,22 @@ int main(int argc, char** argv) {
|
||||
auto t = std::chrono::high_resolution_clock::now();
|
||||
|
||||
Packet* packet = nullptr;
|
||||
int framesSinceLastFlush = 0;
|
||||
int framesSinceMasterDisconnect = 0;
|
||||
int framesSinceChatDisconnect = 0;
|
||||
int framesSinceLastUsersSave = 0;
|
||||
int framesSinceLastSQLPing = 0;
|
||||
int framesSinceLastUser = 0;
|
||||
uint32_t framesSinceLastFlush = 0;
|
||||
uint32_t framesSinceMasterDisconnect = 0;
|
||||
uint32_t framesSinceChatDisconnect = 0;
|
||||
uint32_t framesSinceLastUsersSave = 0;
|
||||
uint32_t framesSinceLastSQLPing = 0;
|
||||
uint32_t framesSinceLastUser = 0;
|
||||
|
||||
const float maxPacketProcessingTime = 1.5f; //0.015f;
|
||||
const int maxPacketsToProcess = 1024;
|
||||
const uint32_t maxPacketsToProcess = 1024;
|
||||
|
||||
bool ready = false;
|
||||
int framesSinceMasterStatus = 0;
|
||||
int framesSinceShutdownSequence = 0;
|
||||
int currentFramerate = highFrameRate;
|
||||
uint32_t framesSinceMasterStatus = 0;
|
||||
uint32_t framesSinceShutdownSequence = 0;
|
||||
uint32_t currentFramerate = highFramerate;
|
||||
|
||||
int ghostingStepCount = 0;
|
||||
uint32_t ghostingStepCount = 0;
|
||||
auto ghostingLastTime = std::chrono::high_resolution_clock::now();
|
||||
|
||||
PerformanceManager::SelectProfile(zoneID);
|
||||
@@ -264,7 +264,7 @@ int main(int argc, char** argv) {
|
||||
}
|
||||
}
|
||||
|
||||
const int bufferSize = 1024;
|
||||
const int32_t bufferSize = 1024;
|
||||
MD5* md5 = new MD5();
|
||||
|
||||
char fileStreamBuffer[1024] = {};
|
||||
@@ -288,6 +288,14 @@ int main(int argc, char** argv) {
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t currentFrameDelta = highFrameDelta;
|
||||
// These values are adjust them selves to the current framerate should it update.
|
||||
uint32_t logFlushTime = 15 * currentFramerate; // 15 seconds in frames
|
||||
uint32_t shutdownTimeout = 10 * 60 * currentFramerate; // 10 minutes in frames
|
||||
uint32_t noMasterConnectionTimeout = 5 * currentFramerate; // 5 seconds in frames
|
||||
uint32_t chatReconnectionTime = 30 * currentFramerate; // 30 seconds in frames
|
||||
uint32_t saveTime = 10 * 60 * currentFramerate; // 10 minutes in frames
|
||||
uint32_t sqlPingTime = 10 * 60 * currentFramerate; // 10 minutes in frames
|
||||
while (true) {
|
||||
Metrics::StartMeasurement(MetricVariable::Frame);
|
||||
Metrics::StartMeasurement(MetricVariable::GameLoop);
|
||||
@@ -300,24 +308,44 @@ int main(int argc, char** argv) {
|
||||
|
||||
const auto occupied = UserManager::Instance()->GetUserCount() != 0;
|
||||
|
||||
uint32_t newFrameDelta = currentFrameDelta;
|
||||
if (!ready) {
|
||||
currentFramerate = highFrameRate;
|
||||
newFrameDelta = highFrameDelta;
|
||||
} else {
|
||||
currentFramerate = PerformanceManager::GetServerFramerate();
|
||||
newFrameDelta = PerformanceManager::GetServerFrameDelta();
|
||||
}
|
||||
|
||||
// Update to the new framerate and scale all timings to said new framerate
|
||||
if (newFrameDelta != currentFrameDelta) {
|
||||
float_t ratioBeforeToAfter = (float)currentFrameDelta / (float)newFrameDelta;
|
||||
currentFrameDelta = newFrameDelta;
|
||||
currentFramerate = MS_TO_FRAMES(newFrameDelta);
|
||||
Game::logger->LogDebug("WorldServer", "Framerate for zone/instance/clone %i/%i/%i is now %i", zoneID, instanceID, cloneID, currentFramerate);
|
||||
logFlushTime = 15 * currentFramerate; // 15 seconds in frames
|
||||
framesSinceLastFlush *= ratioBeforeToAfter;
|
||||
shutdownTimeout = 10 * 60 * currentFramerate; // 10 minutes in frames
|
||||
framesSinceLastUser *= ratioBeforeToAfter;
|
||||
noMasterConnectionTimeout = 5 * currentFramerate; // 5 seconds in frames
|
||||
framesSinceMasterDisconnect *= ratioBeforeToAfter;
|
||||
chatReconnectionTime = 30 * currentFramerate; // 30 seconds in frames
|
||||
framesSinceChatDisconnect *= ratioBeforeToAfter;
|
||||
saveTime = 10 * 60 * currentFramerate; // 10 minutes in frames
|
||||
framesSinceLastUsersSave *= ratioBeforeToAfter;
|
||||
sqlPingTime = 10 * 60 * currentFramerate; // 10 minutes in frames
|
||||
framesSinceLastSQLPing *= ratioBeforeToAfter;
|
||||
}
|
||||
|
||||
//Warning if we ran slow
|
||||
if (deltaTime > currentFramerate) {
|
||||
Game::logger->Log("WorldServer", "We're running behind, dT: %f > %f (framerate)", deltaTime, currentFramerate);
|
||||
if (deltaTime > currentFrameDelta) {
|
||||
Game::logger->Log("WorldServer", "We're running behind, dT: %f > %f (framerate %i)", deltaTime, currentFrameDelta, currentFramerate);
|
||||
}
|
||||
|
||||
//Check if we're still connected to master:
|
||||
if (!Game::server->GetIsConnectedToMaster()) {
|
||||
framesSinceMasterDisconnect++;
|
||||
|
||||
int framesToWaitForMaster = ready ? 10 : 200;
|
||||
if (framesSinceMasterDisconnect >= framesToWaitForMaster && !Game::shouldShutdown) {
|
||||
Game::logger->Log("WorldServer", "Game loop running but no connection to master for %d frames, shutting down", framesToWaitForMaster);
|
||||
if (framesSinceMasterDisconnect >= noMasterConnectionTimeout && !Game::shouldShutdown) {
|
||||
Game::logger->Log("WorldServer", "Game loop running but no connection to master for %d frames, shutting down", noMasterConnectionTimeout);
|
||||
Game::shouldShutdown = true;
|
||||
}
|
||||
} else framesSinceMasterDisconnect = 0;
|
||||
@@ -326,8 +354,7 @@ int main(int argc, char** argv) {
|
||||
if (!chatConnected) {
|
||||
framesSinceChatDisconnect++;
|
||||
|
||||
// Attempt to reconnect every 30 seconds.
|
||||
if (framesSinceChatDisconnect >= 2000) {
|
||||
if (framesSinceChatDisconnect >= chatReconnectionTime) {
|
||||
framesSinceChatDisconnect = 0;
|
||||
|
||||
Game::chatServer->Connect(masterIP.c_str(), chatPort, "3.25 ND1", 8);
|
||||
@@ -379,7 +406,7 @@ int main(int argc, char** argv) {
|
||||
UserManager::Instance()->DeletePendingRemovals();
|
||||
|
||||
auto t1 = std::chrono::high_resolution_clock::now();
|
||||
for (int curPacket = 0; curPacket < maxPacketsToProcess && timeSpent < maxPacketProcessingTime; curPacket++) {
|
||||
for (uint32_t curPacket = 0; curPacket < maxPacketsToProcess && timeSpent < maxPacketProcessingTime; curPacket++) {
|
||||
packet = Game::server->Receive();
|
||||
if (packet) {
|
||||
auto t1 = std::chrono::high_resolution_clock::now();
|
||||
@@ -404,7 +431,7 @@ int main(int argc, char** argv) {
|
||||
Metrics::EndMeasurement(MetricVariable::UpdateReplica);
|
||||
|
||||
//Push our log every 15s:
|
||||
if (framesSinceLastFlush >= 1000) {
|
||||
if (framesSinceLastFlush >= logFlushTime) {
|
||||
Game::logger->Flush();
|
||||
framesSinceLastFlush = 0;
|
||||
} else framesSinceLastFlush++;
|
||||
@@ -421,7 +448,7 @@ int main(int argc, char** argv) {
|
||||
}
|
||||
|
||||
//Save all connected users every 10 minutes:
|
||||
if (framesSinceLastUsersSave >= 40000 && zoneID != 0) {
|
||||
if (framesSinceLastUsersSave >= saveTime && zoneID != 0) {
|
||||
UserManager::Instance()->SaveAllActiveCharacters();
|
||||
framesSinceLastUsersSave = 0;
|
||||
|
||||
@@ -431,10 +458,10 @@ int main(int argc, char** argv) {
|
||||
} else framesSinceLastUsersSave++;
|
||||
|
||||
//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:
|
||||
std::string masterIP;
|
||||
int masterPort;
|
||||
uint32_t masterPort;
|
||||
sql::PreparedStatement* stmt = Database::CreatePreppedStmt("SELECT ip, port FROM servers WHERE name='master';");
|
||||
auto res = stmt->executeQuery();
|
||||
while (res->next()) {
|
||||
@@ -452,7 +479,7 @@ int main(int argc, char** argv) {
|
||||
|
||||
Metrics::StartMeasurement(MetricVariable::Sleep);
|
||||
|
||||
t += std::chrono::milliseconds(currentFramerate);
|
||||
t += std::chrono::milliseconds(currentFrameDelta);
|
||||
std::this_thread::sleep_until(t);
|
||||
|
||||
Metrics::EndMeasurement(MetricVariable::Sleep);
|
||||
@@ -483,7 +510,7 @@ int main(int argc, char** argv) {
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
dLogger* SetupLogger(int zoneID, int instanceID) {
|
||||
dLogger* SetupLogger(uint32_t zoneID, uint32_t instanceID) {
|
||||
std::string logPath = (BinaryPathFinder::GetBinaryDir() / ("logs/WorldServer_" + std::to_string(zoneID) + "_" + std::to_string(instanceID) + "_" + std::to_string(time(nullptr)) + ".log")).string();
|
||||
bool logToConsole = false;
|
||||
bool logDebugStatements = false;
|
||||
@@ -525,7 +552,7 @@ void HandlePacketChat(Packet* packet) {
|
||||
|
||||
//Write our stream outwards:
|
||||
CBITSTREAM;
|
||||
for (int i = 0; i < inStream.GetNumberOfBytesUsed(); i++) {
|
||||
for (BitSize_t i = 0; i < inStream.GetNumberOfBytesUsed(); i++) {
|
||||
bitStream.Write(packet->data[i + 16]); //16 bytes == header + playerID to skip
|
||||
}
|
||||
|
||||
@@ -544,7 +571,7 @@ void HandlePacketChat(Packet* packet) {
|
||||
|
||||
uint32_t len;
|
||||
inStream.Read<uint32_t>(len);
|
||||
for (int i = 0; len > i; i++) {
|
||||
for (uint32_t i = 0; len > i; i++) {
|
||||
char character;
|
||||
inStream.Read<char>(character);
|
||||
title += character;
|
||||
@@ -552,7 +579,7 @@ void HandlePacketChat(Packet* packet) {
|
||||
|
||||
len = 0;
|
||||
inStream.Read<uint32_t>(len);
|
||||
for (int i = 0; len > i; i++) {
|
||||
for (uint32_t i = 0; len > i; i++) {
|
||||
char character;
|
||||
inStream.Read<char>(character);
|
||||
msg += character;
|
||||
@@ -805,7 +832,7 @@ void HandlePacket(Packet* packet) {
|
||||
uint32_t len;
|
||||
inStream.Read(len);
|
||||
|
||||
for (int i = 0; i < len; i++) {
|
||||
for (uint32_t i = 0; i < len; i++) {
|
||||
char character; inStream.Read<char>(character);
|
||||
username += character;
|
||||
}
|
||||
@@ -1048,7 +1075,7 @@ void HandlePacket(Packet* packet) {
|
||||
//Check for BBB models:
|
||||
auto stmt = Database::CreatePreppedStmt("SELECT ugc_id FROM properties_contents WHERE lot=14 AND property_id=?");
|
||||
|
||||
int templateId = result.getIntField(0);
|
||||
int32_t templateId = result.getIntField(0);
|
||||
|
||||
result.finalize();
|
||||
|
||||
|
Reference in New Issue
Block a user