2021-12-05 17:54:36 +00:00
|
|
|
#include <iostream>
|
|
|
|
#include <string>
|
|
|
|
#include <ctime>
|
2024-01-02 03:50:00 +00:00
|
|
|
#include <csignal>
|
2021-12-05 17:54:36 +00:00
|
|
|
#include <chrono>
|
|
|
|
#include <thread>
|
|
|
|
|
|
|
|
//DLU Includes:
|
|
|
|
#include "dCommonVars.h"
|
|
|
|
#include "dServer.h"
|
2023-10-21 23:31:55 +00:00
|
|
|
#include "Logger.h"
|
2021-12-05 17:54:36 +00:00
|
|
|
#include "Database.h"
|
|
|
|
#include "dConfig.h"
|
|
|
|
#include "Diagnostics.h"
|
2022-11-27 11:59:59 +00:00
|
|
|
#include "BinaryPathFinder.h"
|
2021-12-05 17:54:36 +00:00
|
|
|
|
|
|
|
//RakNet includes:
|
|
|
|
#include "RakNetDefines.h"
|
2024-01-05 12:33:52 +00:00
|
|
|
#include "MessageIdentifiers.h"
|
2021-12-05 17:54:36 +00:00
|
|
|
|
|
|
|
//Auth includes:
|
|
|
|
#include "AuthPackets.h"
|
2023-05-03 21:38:32 +00:00
|
|
|
#include "eConnectionType.h"
|
|
|
|
#include "eServerMessageType.h"
|
|
|
|
#include "eAuthMessageType.h"
|
2021-12-05 17:54:36 +00:00
|
|
|
|
|
|
|
#include "Game.h"
|
|
|
|
namespace Game {
|
2023-10-21 23:31:55 +00:00
|
|
|
Logger* logger = nullptr;
|
2022-12-15 14:13:49 +00:00
|
|
|
dServer* server = nullptr;
|
|
|
|
dConfig* config = nullptr;
|
2024-01-02 03:50:00 +00:00
|
|
|
Game::signal_t lastSignal = 0;
|
2023-07-23 21:59:43 +00:00
|
|
|
std::mt19937 randomEngine;
|
2021-12-05 17:54:36 +00:00
|
|
|
}
|
|
|
|
|
2023-10-21 23:31:55 +00:00
|
|
|
Logger* SetupLogger();
|
2021-12-05 17:54:36 +00:00
|
|
|
void HandlePacket(Packet* packet);
|
|
|
|
|
|
|
|
int main(int argc, char** argv) {
|
2022-12-16 10:24:02 +00:00
|
|
|
constexpr uint32_t authFramerate = mediumFramerate;
|
|
|
|
constexpr uint32_t authFrameDelta = mediumFrameDelta;
|
2021-12-05 17:54:36 +00:00
|
|
|
Diagnostics::SetProcessName("Auth");
|
|
|
|
Diagnostics::SetProcessFileName(argv[0]);
|
|
|
|
Diagnostics::Initialize();
|
|
|
|
|
2024-01-02 03:50:00 +00:00
|
|
|
std::signal(SIGINT, Game::OnSignal);
|
|
|
|
std::signal(SIGTERM, Game::OnSignal);
|
|
|
|
|
2021-12-05 17:54:36 +00:00
|
|
|
//Create all the objects we need to run our service:
|
|
|
|
Game::logger = SetupLogger();
|
2022-12-15 14:13:49 +00:00
|
|
|
if (!Game::logger) return EXIT_FAILURE;
|
|
|
|
|
|
|
|
//Read our config:
|
2023-12-30 13:07:49 +00:00
|
|
|
Game::config = new dConfig("authconfig.ini");
|
2022-12-15 14:13:49 +00:00
|
|
|
Game::logger->SetLogToConsole(Game::config->GetValue("log_to_console") != "0");
|
|
|
|
Game::logger->SetLogDebugStatements(Game::config->GetValue("log_debug_statements") == "1");
|
|
|
|
|
2023-10-21 23:31:55 +00:00
|
|
|
LOG("Starting Auth server...");
|
2023-12-31 06:26:49 +00:00
|
|
|
LOG("Version: %s", PROJECT_VERSION);
|
2023-10-21 23:31:55 +00:00
|
|
|
LOG("Compiled on: %s", __TIMESTAMP__);
|
2021-12-05 17:54:36 +00:00
|
|
|
|
|
|
|
try {
|
2023-11-18 00:47:18 +00:00
|
|
|
Database::Connect();
|
2021-12-05 17:54:36 +00:00
|
|
|
} catch (sql::SQLException& ex) {
|
2023-10-21 23:31:55 +00:00
|
|
|
LOG("Got an error while connecting to the database: %s", ex.what());
|
2022-04-09 22:35:01 +00:00
|
|
|
Database::Destroy("AuthServer");
|
2021-12-05 17:54:36 +00:00
|
|
|
delete Game::server;
|
|
|
|
delete Game::logger;
|
2022-12-15 14:13:49 +00:00
|
|
|
return EXIT_FAILURE;
|
2021-12-05 17:54:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//Find out the master's IP:
|
|
|
|
std::string masterIP;
|
2022-12-16 10:24:02 +00:00
|
|
|
uint32_t masterPort = 1500;
|
2021-12-05 17:54:36 +00:00
|
|
|
|
2023-11-18 00:47:18 +00:00
|
|
|
auto masterInfo = Database::Get()->GetMasterInfo();
|
|
|
|
if (masterInfo) {
|
|
|
|
masterIP = masterInfo->ip;
|
|
|
|
masterPort = masterInfo->port;
|
|
|
|
}
|
2024-01-02 03:50:00 +00:00
|
|
|
LOG("Master is at %s:%d", masterIP.c_str(), masterPort);
|
2021-12-05 17:54:36 +00:00
|
|
|
|
2023-07-23 21:59:43 +00:00
|
|
|
Game::randomEngine = std::mt19937(time(0));
|
|
|
|
|
2021-12-05 17:54:36 +00:00
|
|
|
//It's safe to pass 'localhost' here, as the IP is only used as the external IP.
|
2024-01-05 00:21:03 +00:00
|
|
|
uint32_t maxClients = 999;
|
2022-12-16 10:24:02 +00:00
|
|
|
uint32_t ourPort = 1001; //LU client is hardcoded to use this for auth port, so I'm making it the default.
|
2024-01-05 00:21:03 +00:00
|
|
|
std::string ourIP = "localhost";
|
|
|
|
GeneralUtils::TryParse(Game::config->GetValue("max_clients"), maxClients);
|
|
|
|
GeneralUtils::TryParse(Game::config->GetValue("auth_server_port"), ourPort);
|
|
|
|
const auto externalIPString = Game::config->GetValue("external_ip");
|
|
|
|
if (!externalIPString.empty()) ourIP = externalIPString;
|
2022-07-25 02:26:51 +00:00
|
|
|
|
2024-01-05 00:21:03 +00:00
|
|
|
Game::server = new dServer(ourIP, ourPort, 0, maxClients, false, true, Game::logger, masterIP, masterPort, ServerType::Auth, Game::config, &Game::lastSignal);
|
2021-12-05 17:54:36 +00:00
|
|
|
|
|
|
|
//Run it until server gets a kill message from Master:
|
|
|
|
auto t = std::chrono::high_resolution_clock::now();
|
|
|
|
Packet* packet = nullptr;
|
2022-12-16 10:24:02 +00:00
|
|
|
constexpr uint32_t logFlushTime = 30 * authFramerate; // 30 seconds in frames
|
|
|
|
constexpr uint32_t sqlPingTime = 10 * 60 * authFramerate; // 10 minutes in frames
|
|
|
|
uint32_t framesSinceLastFlush = 0;
|
|
|
|
uint32_t framesSinceMasterDisconnect = 0;
|
|
|
|
uint32_t framesSinceLastSQLPing = 0;
|
2021-12-05 17:54:36 +00:00
|
|
|
|
2023-11-22 02:05:15 +00:00
|
|
|
AuthPackets::LoadClaimCodes();
|
|
|
|
|
2024-01-02 03:50:00 +00:00
|
|
|
Game::logger->Flush(); // once immediately before main loop
|
|
|
|
while (!Game::ShouldShutdown()) {
|
2021-12-05 17:54:36 +00:00
|
|
|
//Check if we're still connected to master:
|
|
|
|
if (!Game::server->GetIsConnectedToMaster()) {
|
|
|
|
framesSinceMasterDisconnect++;
|
|
|
|
|
2024-01-02 03:50:00 +00:00
|
|
|
if (framesSinceMasterDisconnect >= authFramerate) {
|
|
|
|
LOG("No connection to master!");
|
2021-12-05 17:54:36 +00:00
|
|
|
break; //Exit our loop, shut down.
|
2024-01-02 03:50:00 +00:00
|
|
|
}
|
2021-12-05 17:54:36 +00:00
|
|
|
} else framesSinceMasterDisconnect = 0;
|
|
|
|
|
|
|
|
//In world we'd update our other systems here.
|
|
|
|
|
|
|
|
//Check for packets here:
|
|
|
|
Game::server->ReceiveFromMaster(); //ReceiveFromMaster also handles the master packets if needed.
|
|
|
|
packet = Game::server->Receive();
|
|
|
|
if (packet) {
|
|
|
|
HandlePacket(packet);
|
|
|
|
Game::server->DeallocatePacket(packet);
|
|
|
|
packet = nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
//Push our log every 30s:
|
2022-12-16 10:24:02 +00:00
|
|
|
if (framesSinceLastFlush >= logFlushTime) {
|
2021-12-05 17:54:36 +00:00
|
|
|
Game::logger->Flush();
|
|
|
|
framesSinceLastFlush = 0;
|
|
|
|
} else framesSinceLastFlush++;
|
|
|
|
|
|
|
|
//Every 10 min we ping our sql server to keep it alive hopefully:
|
2022-12-16 10:24:02 +00:00
|
|
|
if (framesSinceLastSQLPing >= sqlPingTime) {
|
2021-12-05 17:54:36 +00:00
|
|
|
//Find out the master's IP for absolutely no reason:
|
|
|
|
std::string masterIP;
|
2022-12-16 10:24:02 +00:00
|
|
|
uint32_t masterPort;
|
2023-11-18 00:47:18 +00:00
|
|
|
auto masterInfo = Database::Get()->GetMasterInfo();
|
|
|
|
if (masterInfo) {
|
|
|
|
masterIP = masterInfo->ip;
|
|
|
|
masterPort = masterInfo->port;
|
2021-12-05 17:54:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
framesSinceLastSQLPing = 0;
|
|
|
|
} else framesSinceLastSQLPing++;
|
|
|
|
|
|
|
|
//Sleep our thread since auth can afford to.
|
2022-12-16 10:24:02 +00:00
|
|
|
t += std::chrono::milliseconds(authFrameDelta); //Auth can run at a lower "fps"
|
2021-12-05 17:54:36 +00:00
|
|
|
std::this_thread::sleep_until(t);
|
|
|
|
}
|
|
|
|
|
2024-01-02 03:50:00 +00:00
|
|
|
LOG("Exited Main Loop! (signal %d)", Game::lastSignal);
|
2021-12-05 17:54:36 +00:00
|
|
|
//Delete our objects here:
|
2022-04-09 22:35:01 +00:00
|
|
|
Database::Destroy("AuthServer");
|
2021-12-05 17:54:36 +00:00
|
|
|
delete Game::server;
|
|
|
|
delete Game::logger;
|
2022-12-15 14:13:49 +00:00
|
|
|
delete Game::config;
|
2021-12-05 17:54:36 +00:00
|
|
|
|
2022-04-09 22:57:18 +00:00
|
|
|
return EXIT_SUCCESS;
|
2021-12-05 17:54:36 +00:00
|
|
|
}
|
|
|
|
|
2023-10-21 23:31:55 +00:00
|
|
|
Logger* SetupLogger() {
|
2022-11-27 11:59:59 +00:00
|
|
|
std::string logPath = (BinaryPathFinder::GetBinaryDir() / ("logs/AuthServer_" + std::to_string(time(nullptr)) + ".log")).string();
|
2021-12-05 17:54:36 +00:00
|
|
|
bool logToConsole = false;
|
2021-12-11 12:29:34 +00:00
|
|
|
bool logDebugStatements = false;
|
2021-12-05 17:54:36 +00:00
|
|
|
#ifdef _DEBUG
|
|
|
|
logToConsole = true;
|
2021-12-11 12:29:34 +00:00
|
|
|
logDebugStatements = true;
|
2021-12-05 17:54:36 +00:00
|
|
|
#endif
|
|
|
|
|
2023-10-21 23:31:55 +00:00
|
|
|
return new Logger(logPath, logToConsole, logDebugStatements);
|
2021-12-05 17:54:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void HandlePacket(Packet* packet) {
|
2023-05-06 18:32:53 +00:00
|
|
|
if (packet->length < 4) return;
|
|
|
|
|
2021-12-05 17:54:36 +00:00
|
|
|
if (packet->data[0] == ID_USER_PACKET_ENUM) {
|
2023-05-03 21:38:32 +00:00
|
|
|
if (static_cast<eConnectionType>(packet->data[1]) == eConnectionType::SERVER) {
|
|
|
|
if (static_cast<eServerMessageType>(packet->data[3]) == eServerMessageType::VERSION_CONFIRM) {
|
2021-12-05 17:54:36 +00:00
|
|
|
AuthPackets::HandleHandshake(Game::server, packet);
|
|
|
|
}
|
2023-05-03 21:38:32 +00:00
|
|
|
} else if (static_cast<eConnectionType>(packet->data[1]) == eConnectionType::AUTH) {
|
|
|
|
if (static_cast<eAuthMessageType>(packet->data[3]) == eAuthMessageType::LOGIN_REQUEST) {
|
2021-12-05 17:54:36 +00:00
|
|
|
AuthPackets::HandleLoginRequest(Game::server, packet);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|