Merge remote-tracking branch 'upstream/main'

This commit is contained in:
David Markowitz 2022-12-20 14:45:15 -08:00
commit 41b8762c8f
12 changed files with 249 additions and 173 deletions

View File

@ -422,11 +422,6 @@ Here is a summary of the commands available in-game. All commands are prefixed b
</table> </table>
# Credits # Credits
## Active Contributors
* [EmosewaMC](https://github.com/EmosewaMC)
* [Jettford](https://github.com/Jettford)
* [Aaron K.](https://github.com/aronwk-aaron)
## DLU Team ## DLU Team
* [DarwinAnim8or](https://github.com/DarwinAnim8or) * [DarwinAnim8or](https://github.com/DarwinAnim8or)
* [Wincent01](https://github.com/Wincent01) * [Wincent01](https://github.com/Wincent01)
@ -434,25 +429,30 @@ Here is a summary of the commands available in-game. All commands are prefixed b
* [averysumner](https://github.com/codeshaunted) * [averysumner](https://github.com/codeshaunted)
* [Jon002](https://github.com/jaller200) * [Jon002](https://github.com/jaller200)
* [Jonny](https://github.com/cuzitsjonny) * [Jonny](https://github.com/cuzitsjonny)
* [Aaron K.](https://github.com/aronwk-aaron)
### Research and tools ### Research and Tools
* [lcdr](https://github.com/lcdr) * [lcdr](https://github.com/lcdr)
* [Xiphoseer](https://github.com/Xiphoseer) * [Xiphoseer](https://github.com/Xiphoseer)
### Community management ### Community Management
* [Neal](https://github.com/NealSpellman) * [Neal](https://github.com/NealSpellman)
### Former contributors ### Logo
* Cole Peterson (BlasterBuilder)
## Active Contributors
* [EmosewaMC](https://github.com/EmosewaMC)
* [Jettford](https://github.com/Jettford)
## Former Contributors
* TheMachine * TheMachine
* Matthew * Matthew
* [Raine](https://github.com/Rainebannister) * [Raine](https://github.com/Rainebannister)
* Bricknave * Bricknave
### Logo ## Special Thanks
* Cole Peterson (BlasterBuilder)
## Special thanks
* humanoid24 * humanoid24
* pwjones1969 * pwjones1969
* [Simon](https://github.com/SimonNitzsche) * [Simon](https://github.com/SimonNitzsche)
* ALL OF THE NETDEVIL AND LEGO TEAMS! * [ALL OF THE NETDEVIL AND LEGO TEAMS!](https://www.mobygames.com/game/macintosh/lego-universe/credits)

View File

@ -32,6 +32,8 @@ dLogger* SetupLogger();
void HandlePacket(Packet* packet); void HandlePacket(Packet* packet);
int main(int argc, char** argv) { int main(int argc, char** argv) {
constexpr uint32_t authFramerate = mediumFramerate;
constexpr uint32_t authFrameDelta = mediumFrameDelta;
Diagnostics::SetProcessName("Auth"); Diagnostics::SetProcessName("Auth");
Diagnostics::SetProcessFileName(argv[0]); Diagnostics::SetProcessFileName(argv[0]);
Diagnostics::Initialize(); Diagnostics::Initialize();
@ -67,7 +69,7 @@ int main(int argc, char** argv) {
//Find out the master's IP: //Find out the master's IP:
std::string masterIP; std::string masterIP;
int masterPort = 1500; uint32_t masterPort = 1500;
sql::PreparedStatement* stmt = Database::CreatePreppedStmt("SELECT ip, port FROM servers WHERE name='master';"); sql::PreparedStatement* stmt = Database::CreatePreppedStmt("SELECT ip, port FROM servers WHERE name='master';");
auto res = stmt->executeQuery(); auto res = stmt->executeQuery();
while (res->next()) { while (res->next()) {
@ -79,8 +81,8 @@ int main(int argc, char** argv) {
delete stmt; delete stmt;
//It's safe to pass 'localhost' here, as the IP is only used as the external IP. //It's safe to pass 'localhost' here, as the IP is only used as the external IP.
int maxClients = 50; uint32_t maxClients = 50;
int ourPort = 1001; //LU client is hardcoded to use this for auth port, so I'm making it the default. uint32_t ourPort = 1001; //LU client is hardcoded to use this for auth port, so I'm making it the default.
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());
@ -89,16 +91,18 @@ int main(int argc, char** argv) {
//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();
Packet* packet = nullptr; Packet* packet = nullptr;
int framesSinceLastFlush = 0; constexpr uint32_t logFlushTime = 30 * authFramerate; // 30 seconds in frames
int framesSinceMasterDisconnect = 0; constexpr uint32_t sqlPingTime = 10 * 60 * authFramerate; // 10 minutes in frames
int framesSinceLastSQLPing = 0; uint32_t framesSinceLastFlush = 0;
uint32_t framesSinceMasterDisconnect = 0;
uint32_t framesSinceLastSQLPing = 0;
while (!Game::shouldShutdown) { 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 >= 30) if (framesSinceMasterDisconnect >= authFramerate)
break; //Exit our loop, shut down. break; //Exit our loop, shut down.
} else framesSinceMasterDisconnect = 0; } else framesSinceMasterDisconnect = 0;
@ -114,16 +118,16 @@ int main(int argc, char** argv) {
} }
//Push our log every 30s: //Push our log every 30s:
if (framesSinceLastFlush >= 900) { if (framesSinceLastFlush >= logFlushTime) {
Game::logger->Flush(); Game::logger->Flush();
framesSinceLastFlush = 0; framesSinceLastFlush = 0;
} else framesSinceLastFlush++; } else 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; uint32_t masterPort;
sql::PreparedStatement* stmt = Database::CreatePreppedStmt("SELECT ip, port FROM servers WHERE name='master';"); sql::PreparedStatement* stmt = Database::CreatePreppedStmt("SELECT ip, port FROM servers WHERE name='master';");
auto res = stmt->executeQuery(); auto res = stmt->executeQuery();
while (res->next()) { while (res->next()) {
@ -138,7 +142,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(authFrameDelta); //Auth can run at a lower "fps"
std::this_thread::sleep_until(t); std::this_thread::sleep_until(t);
} }

View File

@ -19,6 +19,9 @@
#include "ChatPacketHandler.h" #include "ChatPacketHandler.h"
#include "Game.h" #include "Game.h"
//RakNet includes:
#include "RakNetDefines.h"
namespace Game { namespace Game {
dLogger* logger = nullptr; dLogger* logger = nullptr;
dServer* server = nullptr; dServer* server = nullptr;
@ -28,8 +31,6 @@ namespace Game {
bool shouldShutdown = false; bool shouldShutdown = false;
} }
//RakNet includes:
#include "RakNetDefines.h"
dLogger* SetupLogger(); dLogger* SetupLogger();
void HandlePacket(Packet* packet); void HandlePacket(Packet* packet);
@ -37,6 +38,8 @@ void HandlePacket(Packet* packet);
PlayerContainer playerContainer; PlayerContainer playerContainer;
int main(int argc, char** argv) { int main(int argc, char** argv) {
constexpr uint32_t chatFramerate = mediumFramerate;
constexpr uint32_t chatFrameDelta = mediumFrameDelta;
Diagnostics::SetProcessName("Chat"); Diagnostics::SetProcessName("Chat");
Diagnostics::SetProcessFileName(argv[0]); Diagnostics::SetProcessFileName(argv[0]);
Diagnostics::Initialize(); Diagnostics::Initialize();
@ -65,7 +68,7 @@ int main(int argc, char** argv) {
Game::assetManager = new AssetManager(clientPath); Game::assetManager = new AssetManager(clientPath);
} catch (std::runtime_error& ex) { } catch (std::runtime_error& ex) {
Game::logger->Log("ChatServer", "Got an error while setting up assets: %s", ex.what()); Game::logger->Log("ChatServer", "Got an error while setting up assets: %s", ex.what());
return EXIT_FAILURE; return EXIT_FAILURE;
} }
@ -87,7 +90,7 @@ int main(int argc, char** argv) {
//Find out the master's IP: //Find out the master's IP:
std::string masterIP; std::string masterIP;
int masterPort = 1000; uint32_t masterPort = 1000;
sql::PreparedStatement* stmt = Database::CreatePreppedStmt("SELECT ip, port FROM servers WHERE name='master';"); sql::PreparedStatement* stmt = Database::CreatePreppedStmt("SELECT ip, port FROM servers WHERE name='master';");
auto res = stmt->executeQuery(); auto res = stmt->executeQuery();
while (res->next()) { while (res->next()) {
@ -99,8 +102,8 @@ int main(int argc, char** argv) {
delete stmt; delete stmt;
//It's safe to pass 'localhost' here, as the IP is only used as the external IP. //It's safe to pass 'localhost' here, as the IP is only used as the external IP.
int maxClients = 50; uint32_t maxClients = 50;
int ourPort = 1501; uint32_t ourPort = 1501;
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());
@ -111,16 +114,18 @@ int main(int argc, char** argv) {
//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();
Packet* packet = nullptr; Packet* packet = nullptr;
int framesSinceLastFlush = 0; constexpr uint32_t logFlushTime = 30 * chatFramerate; // 30 seconds in frames
int framesSinceMasterDisconnect = 0; constexpr uint32_t sqlPingTime = 10 * 60 * chatFramerate; // 10 minutes in frames
int framesSinceLastSQLPing = 0; uint32_t framesSinceLastFlush = 0;
uint32_t framesSinceMasterDisconnect = 0;
uint32_t framesSinceLastSQLPing = 0;
while (!Game::shouldShutdown) { 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 >= 30) if (framesSinceMasterDisconnect >= chatFramerate)
break; //Exit our loop, shut down. break; //Exit our loop, shut down.
} else framesSinceMasterDisconnect = 0; } else framesSinceMasterDisconnect = 0;
@ -136,16 +141,16 @@ int main(int argc, char** argv) {
} }
//Push our log every 30s: //Push our log every 30s:
if (framesSinceLastFlush >= 900) { if (framesSinceLastFlush >= logFlushTime) {
Game::logger->Flush(); Game::logger->Flush();
framesSinceLastFlush = 0; framesSinceLastFlush = 0;
} else framesSinceLastFlush++; } else 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; uint32_t masterPort;
sql::PreparedStatement* stmt = Database::CreatePreppedStmt("SELECT ip, port FROM servers WHERE name='master';"); sql::PreparedStatement* stmt = Database::CreatePreppedStmt("SELECT ip, port FROM servers WHERE name='master';");
auto res = stmt->executeQuery(); auto res = stmt->executeQuery();
while (res->next()) { while (res->next()) {
@ -160,7 +165,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(chatFrameDelta); //Chat can run at a lower "fps"
std::this_thread::sleep_until(t); std::this_thread::sleep_until(t);
} }

View File

@ -6,15 +6,25 @@
#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 // These are the same define, but they mean two different things in different contexts
const int mediumFramerate = 33; //30fps // so a different define to distinguish what calculation is happening will help clarity.
const int lowFramerate = 66; //15fps #define FRAMES_TO_MS(x) 1000 / x
#define MS_TO_FRAMES(x) 1000 / x
//=========== 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

@ -208,7 +208,7 @@ void ScriptedActivityComponent::PlayerLeave(LWOOBJID playerID) {
} }
void ScriptedActivityComponent::Update(float deltaTime) { void ScriptedActivityComponent::Update(float deltaTime) {
std::vector<Lobby*> lobbiesToRemove{};
// Ticks all the lobbies, not applicable for non-instance activities // Ticks all the lobbies, not applicable for non-instance activities
for (Lobby* lobby : m_Queue) { for (Lobby* lobby : m_Queue) {
for (LobbyPlayer* player : lobby->players) { for (LobbyPlayer* player : lobby->players) {
@ -219,6 +219,11 @@ void ScriptedActivityComponent::Update(float deltaTime) {
} }
} }
if (lobby->players.empty()) {
lobbiesToRemove.push_back(lobby);
continue;
}
// Update the match time for all players // Update the match time for all players
if (m_ActivityInfo.maxTeamSize != 1 && lobby->players.size() >= m_ActivityInfo.minTeamSize if (m_ActivityInfo.maxTeamSize != 1 && lobby->players.size() >= m_ActivityInfo.minTeamSize
|| m_ActivityInfo.maxTeamSize == 1 && lobby->players.size() >= m_ActivityInfo.minTeams) { || m_ActivityInfo.maxTeamSize == 1 && lobby->players.size() >= m_ActivityInfo.minTeams) {
@ -262,13 +267,17 @@ void ScriptedActivityComponent::Update(float deltaTime) {
// The timer has elapsed, start the instance // The timer has elapsed, start the instance
if (lobby->timer <= 0.0f) { if (lobby->timer <= 0.0f) {
Game::logger->Log("ScriptedActivityComponent", "Setting up instance."); Game::logger->Log("ScriptedActivityComponent", "Setting up instance.");
ActivityInstance* instance = NewInstance(); ActivityInstance* instance = NewInstance();
LoadPlayersIntoInstance(instance, lobby->players); LoadPlayersIntoInstance(instance, lobby->players);
RemoveLobby(lobby);
instance->StartZone(); instance->StartZone();
lobbiesToRemove.push_back(lobby);
} }
} }
while (!lobbiesToRemove.empty()) {
RemoveLobby(lobbiesToRemove.front());
lobbiesToRemove.erase(lobbiesToRemove.begin());
}
} }
void ScriptedActivityComponent::RemoveLobby(Lobby* lobby) { void ScriptedActivityComponent::RemoveLobby(Lobby* lobby) {

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

@ -52,8 +52,8 @@ namespace Game {
} //namespace Game } //namespace Game
bool shutdownSequenceStarted = false; bool shutdownSequenceStarted = false;
void ShutdownSequence(int signal = -1); void ShutdownSequence(int32_t signal = -1);
int FinalizeShutdown(int signal = -1); int32_t FinalizeShutdown(int32_t signal = -1);
dLogger* SetupLogger(); dLogger* SetupLogger();
void StartAuthServer(); void StartAuthServer();
void StartChatServer(); void StartChatServer();
@ -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();
@ -73,8 +75,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, [](int signal) { ShutdownSequence(EXIT_FAILURE); }); signal(SIGINT, [](int32_t signal) { ShutdownSequence(EXIT_FAILURE); });
signal(SIGTERM, [](int signal) { ShutdownSequence(EXIT_FAILURE); }); signal(SIGTERM, [](int32_t 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();
@ -237,8 +239,8 @@ int main(int argc, char** argv) {
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }
int maxClients = 999; uint32_t maxClients = 999;
int ourPort = 1000; uint32_t ourPort = 1000;
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"));
@ -287,9 +289,13 @@ 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;
int framesSinceLastFlush = 0; constexpr uint32_t logFlushTime = 15 * masterFramerate;
int framesSinceLastSQLPing = 0; constexpr uint32_t sqlPingTime = 10 * 60 * masterFramerate;
int framesSinceKillUniverseCommand = 0; constexpr uint32_t shutdownUniverseTime = 10 * 60 * masterFramerate;
constexpr uint32_t instanceReadyTimeout = 30 * masterFramerate;
uint32_t framesSinceLastFlush = 0;
uint32_t framesSinceLastSQLPing = 0;
uint32_t framesSinceKillUniverseCommand = 0;
while (true) { while (true) {
//In world we'd update our other systems here. //In world we'd update our other systems here.
@ -303,17 +309,17 @@ 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; uint32_t masterPort;
sql::PreparedStatement* stmt = Database::CreatePreppedStmt("SELECT ip, port FROM servers WHERE name='master';"); sql::PreparedStatement* stmt = Database::CreatePreppedStmt("SELECT ip, port FROM servers WHERE name='master';");
auto res = stmt->executeQuery(); auto res = stmt->executeQuery();
while (res->next()) { while (res->next()) {
@ -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);
@ -644,7 +652,7 @@ void HandlePacket(Packet* packet) {
uint32_t len; uint32_t len;
inStream.Read<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; char character;
inStream.Read<char>(character); inStream.Read<char>(character);
password += character; password += character;
@ -670,7 +678,7 @@ void HandlePacket(Packet* packet) {
uint32_t len; uint32_t len;
inStream.Read<uint32_t>(len); inStream.Read<uint32_t>(len);
for (int i = 0; i < len; i++) { for (uint32_t i = 0; i < len; i++) {
char character; inStream.Read<char>(character); char character; inStream.Read<char>(character);
password += character; password += character;
} }
@ -718,11 +726,15 @@ void HandlePacket(Packet* packet) {
RakNet::BitStream inStream(packet->data, packet->length, false); RakNet::BitStream inStream(packet->data, packet->length, false);
uint64_t header = inStream.Read(header); uint64_t header = inStream.Read(header);
int zoneID; int32_t 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,15 +818,20 @@ 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
} }
void ShutdownSequence(int signal) { void ShutdownSequence(int32_t signal) {
if (shutdownSequenceStarted) { if (shutdownSequenceStarted) {
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;
} }
@ -890,7 +905,7 @@ void ShutdownSequence(int signal) {
FinalizeShutdown(signal); FinalizeShutdown(signal);
} }
int FinalizeShutdown(int signal) { int32_t FinalizeShutdown(int32_t 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;

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);
@ -91,10 +79,10 @@ void PerformanceManager::SelectProfile(LWOMAPID mapID) {
m_CurrentProfile = pair->second; m_CurrentProfile = pair->second;
} }
uint32_t PerformanceManager::GetServerFramerate() { uint32_t PerformanceManager::GetServerFrameDelta() {
if (UserManager::Instance()->GetUserCount() == 0) { if (UserManager::Instance()->GetUserCount() == 0) {
return m_InactiveProfile.serverFramerate; return m_InactiveProfile.serverFrameDelta;
} }
return m_CurrentProfile.serverFramerate; return m_CurrentProfile.serverFrameDelta;
} }

View File

@ -5,21 +5,16 @@
#include "dCommonVars.h" #include "dCommonVars.h"
struct PerformanceProfile { struct PerformanceProfile {
uint32_t serverFramerate; uint32_t serverFrameDelta;
}; };
class PerformanceManager { class PerformanceManager {
public: public:
~PerformanceManager();
static void SelectProfile(LWOMAPID mapID); static void SelectProfile(LWOMAPID mapID);
static uint32_t GetServerFramerate(); static uint32_t GetServerFrameDelta();
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

@ -82,7 +82,7 @@ void WorldShutdownProcess(uint32_t zoneId);
void FinalizeShutdown(); void FinalizeShutdown();
void SendShutdownMessageToMaster(); void SendShutdownMessageToMaster();
dLogger* SetupLogger(int zoneID, int instanceID); dLogger* SetupLogger(uint32_t zoneID, uint32_t instanceID);
void HandlePacketChat(Packet* packet); void HandlePacketChat(Packet* packet);
void HandlePacket(Packet* packet); void HandlePacket(Packet* packet);
@ -92,8 +92,8 @@ struct tempSessionInfo {
}; };
std::map<std::string, tempSessionInfo> m_PendingUsers; std::map<std::string, tempSessionInfo> m_PendingUsers;
int instanceID = 0; uint32_t instanceID = 0;
int g_CloneID = 0; uint32_t g_CloneID = 0;
std::string databaseChecksum = ""; std::string databaseChecksum = "";
int main(int argc, char** argv) { int main(int argc, char** argv) {
@ -107,13 +107,13 @@ int main(int argc, char** argv) {
signal(SIGINT, [](int) { WorldShutdownSequence(); }); signal(SIGINT, [](int) { WorldShutdownSequence(); });
signal(SIGTERM, [](int) { WorldShutdownSequence(); }); signal(SIGTERM, [](int) { WorldShutdownSequence(); });
int zoneID = 1000; uint32_t zoneID = 1000;
int cloneID = 0; uint32_t cloneID = 0;
int maxClients = 8; uint32_t maxClients = 8;
int ourPort = 2007; uint32_t ourPort = 2007;
//Check our arguments: //Check our arguments:
for (int i = 0; i < argc; ++i) { for (int32_t i = 0; i < argc; ++i) {
std::string argument(argv[i]); std::string argument(argv[i]);
if (argument == "-zone") zoneID = atoi(argv[i + 1]); if (argument == "-zone") zoneID = atoi(argv[i + 1]);
@ -185,7 +185,7 @@ int main(int argc, char** argv) {
//Find out the master's IP: //Find out the master's IP:
std::string masterIP = "localhost"; std::string masterIP = "localhost";
int masterPort = 1000; uint32_t masterPort = 1000;
sql::PreparedStatement* stmt = Database::CreatePreppedStmt("SELECT ip, port FROM servers WHERE name='master';"); sql::PreparedStatement* stmt = Database::CreatePreppedStmt("SELECT ip, port FROM servers WHERE name='master';");
auto res = stmt->executeQuery(); auto res = stmt->executeQuery();
while (res->next()) { 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); 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; uint32_t chatPort = 1501;
if (Game::config->GetValue("chat_server_port") != "") chatPort = std::atoi(Game::config->GetValue("chat_server_port").c_str()); 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); 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(); auto t = std::chrono::high_resolution_clock::now();
Packet* packet = nullptr; Packet* packet = nullptr;
int framesSinceLastFlush = 0; uint32_t framesSinceLastFlush = 0;
int framesSinceMasterDisconnect = 0; uint32_t framesSinceMasterDisconnect = 0;
int framesSinceChatDisconnect = 0; uint32_t framesSinceChatDisconnect = 0;
int framesSinceLastUsersSave = 0; uint32_t framesSinceLastUsersSave = 0;
int framesSinceLastSQLPing = 0; uint32_t framesSinceLastSQLPing = 0;
int framesSinceLastUser = 0; uint32_t framesSinceLastUser = 0;
const float maxPacketProcessingTime = 1.5f; //0.015f; const float maxPacketProcessingTime = 1.5f; //0.015f;
const int maxPacketsToProcess = 1024; const uint32_t maxPacketsToProcess = 1024;
bool ready = false; bool ready = false;
int framesSinceMasterStatus = 0; uint32_t framesSinceMasterStatus = 0;
int framesSinceShutdownSequence = 0; uint32_t framesSinceShutdownSequence = 0;
int currentFramerate = highFrameRate; uint32_t currentFramerate = highFramerate;
int ghostingStepCount = 0; uint32_t ghostingStepCount = 0;
auto ghostingLastTime = std::chrono::high_resolution_clock::now(); auto ghostingLastTime = std::chrono::high_resolution_clock::now();
PerformanceManager::SelectProfile(zoneID); 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(); MD5* md5 = new MD5();
char fileStreamBuffer[1024] = {}; 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) { while (true) {
Metrics::StartMeasurement(MetricVariable::Frame); Metrics::StartMeasurement(MetricVariable::Frame);
Metrics::StartMeasurement(MetricVariable::GameLoop); Metrics::StartMeasurement(MetricVariable::GameLoop);
@ -300,24 +308,44 @@ int main(int argc, char** argv) {
const auto occupied = UserManager::Instance()->GetUserCount() != 0; const auto occupied = UserManager::Instance()->GetUserCount() != 0;
uint32_t newFrameDelta = currentFrameDelta;
if (!ready) { if (!ready) {
currentFramerate = highFrameRate; newFrameDelta = highFrameDelta;
} else { } 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 //Warning if we ran slow
if (deltaTime > currentFramerate) { if (deltaTime > currentFrameDelta) {
Game::logger->Log("WorldServer", "We're running behind, dT: %f > %f (framerate)", deltaTime, currentFramerate); Game::logger->Log("WorldServer", "We're running behind, dT: %f > %f (framerate %i)", deltaTime, currentFrameDelta, currentFramerate);
} }
//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++;
int framesToWaitForMaster = ready ? 10 : 200; if (framesSinceMasterDisconnect >= noMasterConnectionTimeout && !Game::shouldShutdown) {
if (framesSinceMasterDisconnect >= framesToWaitForMaster && !Game::shouldShutdown) { Game::logger->Log("WorldServer", "Game loop running but no connection to master for %d frames, shutting down", noMasterConnectionTimeout);
Game::logger->Log("WorldServer", "Game loop running but no connection to master for %d frames, shutting down", framesToWaitForMaster);
Game::shouldShutdown = true; Game::shouldShutdown = true;
} }
} else framesSinceMasterDisconnect = 0; } else framesSinceMasterDisconnect = 0;
@ -326,8 +354,7 @@ int main(int argc, char** argv) {
if (!chatConnected) { if (!chatConnected) {
framesSinceChatDisconnect++; framesSinceChatDisconnect++;
// Attempt to reconnect every 30 seconds. if (framesSinceChatDisconnect >= chatReconnectionTime) {
if (framesSinceChatDisconnect >= 2000) {
framesSinceChatDisconnect = 0; framesSinceChatDisconnect = 0;
Game::chatServer->Connect(masterIP.c_str(), chatPort, "3.25 ND1", 8); Game::chatServer->Connect(masterIP.c_str(), chatPort, "3.25 ND1", 8);
@ -379,7 +406,7 @@ int main(int argc, char** argv) {
UserManager::Instance()->DeletePendingRemovals(); UserManager::Instance()->DeletePendingRemovals();
auto t1 = std::chrono::high_resolution_clock::now(); 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(); packet = Game::server->Receive();
if (packet) { if (packet) {
auto t1 = std::chrono::high_resolution_clock::now(); auto t1 = std::chrono::high_resolution_clock::now();
@ -404,7 +431,7 @@ int main(int argc, char** argv) {
Metrics::EndMeasurement(MetricVariable::UpdateReplica); Metrics::EndMeasurement(MetricVariable::UpdateReplica);
//Push our log every 15s: //Push our log every 15s:
if (framesSinceLastFlush >= 1000) { if (framesSinceLastFlush >= logFlushTime) {
Game::logger->Flush(); Game::logger->Flush();
framesSinceLastFlush = 0; framesSinceLastFlush = 0;
} else framesSinceLastFlush++; } else framesSinceLastFlush++;
@ -421,7 +448,7 @@ int main(int argc, char** argv) {
} }
//Save all connected users every 10 minutes: //Save all connected users every 10 minutes:
if (framesSinceLastUsersSave >= 40000 && zoneID != 0) { if (framesSinceLastUsersSave >= saveTime && zoneID != 0) {
UserManager::Instance()->SaveAllActiveCharacters(); UserManager::Instance()->SaveAllActiveCharacters();
framesSinceLastUsersSave = 0; framesSinceLastUsersSave = 0;
@ -431,10 +458,10 @@ int main(int argc, char** argv) {
} else framesSinceLastUsersSave++; } else framesSinceLastUsersSave++;
//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; uint32_t masterPort;
sql::PreparedStatement* stmt = Database::CreatePreppedStmt("SELECT ip, port FROM servers WHERE name='master';"); sql::PreparedStatement* stmt = Database::CreatePreppedStmt("SELECT ip, port FROM servers WHERE name='master';");
auto res = stmt->executeQuery(); auto res = stmt->executeQuery();
while (res->next()) { while (res->next()) {
@ -452,7 +479,7 @@ int main(int argc, char** argv) {
Metrics::StartMeasurement(MetricVariable::Sleep); Metrics::StartMeasurement(MetricVariable::Sleep);
t += std::chrono::milliseconds(currentFramerate); t += std::chrono::milliseconds(currentFrameDelta);
std::this_thread::sleep_until(t); std::this_thread::sleep_until(t);
Metrics::EndMeasurement(MetricVariable::Sleep); Metrics::EndMeasurement(MetricVariable::Sleep);
@ -483,7 +510,7 @@ int main(int argc, char** argv) {
return EXIT_SUCCESS; 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(); 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 logToConsole = false;
bool logDebugStatements = false; bool logDebugStatements = false;
@ -525,7 +552,7 @@ void HandlePacketChat(Packet* packet) {
//Write our stream outwards: //Write our stream outwards:
CBITSTREAM; 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 bitStream.Write(packet->data[i + 16]); //16 bytes == header + playerID to skip
} }
@ -544,7 +571,7 @@ void HandlePacketChat(Packet* packet) {
uint32_t len; uint32_t len;
inStream.Read<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; char character;
inStream.Read<char>(character); inStream.Read<char>(character);
title += character; title += character;
@ -552,7 +579,7 @@ void HandlePacketChat(Packet* packet) {
len = 0; len = 0;
inStream.Read<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; char character;
inStream.Read<char>(character); inStream.Read<char>(character);
msg += character; msg += character;
@ -805,7 +832,7 @@ void HandlePacket(Packet* packet) {
uint32_t len; uint32_t len;
inStream.Read(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); char character; inStream.Read<char>(character);
username += character; username += character;
} }
@ -1048,7 +1075,7 @@ void HandlePacket(Packet* packet) {
//Check for BBB models: //Check for BBB models:
auto stmt = Database::CreatePreppedStmt("SELECT ugc_id FROM properties_contents WHERE lot=14 AND property_id=?"); 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(); result.finalize();

View File

@ -1,18 +1,17 @@
# CREDITS # CREDITS
## Developers ## DLU Team
DarwinAnim8or (Max) DarwinAnim8or (Max)
Wincent01 Wincent01
Mick Mick
averysumner (codeshaunted) averysumner (codeshaunted)
Jon002 Jon002
Jonny Jonny
EmosewaMC
Jettford
## Research & Tooling
Xiphoseer Xiphoseer
lcdr lcdr
Aaron K.
## Community Management
Neal Neal
## Active Contributors
EmosewaMC
Jettford