mirror of
https://github.com/EQEmu/Server.git
synced 2025-12-13 10:31:29 +00:00
* Beginning of cleanup * More cleanup * More cleanup * Enc cleanup * client manager cleanup * client cleanup * More cleanup * More cleanup * Cleanup * More cleanup, account context, account management * Remove positional fmt bindings * Use LoginAccountContext * Update loginserver_webserver.cpp * Remove comments * Port CreateLoginServerAccount to repositories * More cleanup * More cleanup * More cleanup * More cleanup * Remove a ton of functions * More cleanup * More cleanup * More cleanup * Cleanup SendClientAuthToWorld * Consolidate world server logic * Update login_accounts_repository.h * Update login_accounts_repository.h * Move api tokens to repositories * Cleanup options * Move everything else to repositories * Update account_management.cpp * uint64 account * Update login_schema.sql * Fix * Update world_server.cpp * auto
219 lines
5.9 KiB
C++
219 lines
5.9 KiB
C++
#include "world_server_manager.h"
|
|
#include "login_server.h"
|
|
#include "login_types.h"
|
|
#include <stdlib.h>
|
|
|
|
#include "../common/eqemu_logsys.h"
|
|
#include "../common/ip_util.h"
|
|
|
|
extern LoginServer server;
|
|
extern bool run_server;
|
|
|
|
WorldServerManager::WorldServerManager()
|
|
{
|
|
int listen_port = server.config.GetVariableInt("general", "listen_port", 5998);
|
|
|
|
m_server_connection = std::make_unique<EQ::Net::ServertalkServer>();
|
|
EQ::Net::ServertalkServerOptions opts;
|
|
opts.port = listen_port;
|
|
opts.ipv6 = false;
|
|
m_server_connection->Listen(opts);
|
|
|
|
LogInfo("Loginserver now listening on port [{}]", listen_port);
|
|
|
|
m_server_connection->OnConnectionIdentified(
|
|
"World", [this](std::shared_ptr<EQ::Net::ServertalkServerConnection> c) {
|
|
LogInfo(
|
|
"New World Server connection from remote_ip [{}] port [{}]",
|
|
c->Handle()->RemoteIP(),
|
|
c->Handle()->RemotePort()
|
|
);
|
|
|
|
auto iter = std::find_if(
|
|
m_world_servers.begin(), m_world_servers.end(),
|
|
[&](const std::unique_ptr<WorldServer> &s) {
|
|
return s->GetConnection()->Handle()->RemoteIP() == c->Handle()->RemoteIP() &&
|
|
s->GetConnection()->Handle()->RemotePort() == c->Handle()->RemotePort();
|
|
}
|
|
);
|
|
|
|
if (iter != m_world_servers.end()) {
|
|
LogInfo(
|
|
"World server already existed for remote_ip [{}] port [{}] removing existing connection.",
|
|
c->Handle()->RemoteIP(),
|
|
c->Handle()->RemotePort()
|
|
);
|
|
|
|
m_world_servers.erase(iter);
|
|
}
|
|
|
|
m_world_servers.push_back(std::make_unique<WorldServer>(c));
|
|
}
|
|
);
|
|
|
|
m_server_connection->OnConnectionRemoved(
|
|
"World", [this](std::shared_ptr<EQ::Net::ServertalkServerConnection> c) {
|
|
auto iter = std::find_if(
|
|
m_world_servers.begin(), m_world_servers.end(),
|
|
[&](const std::unique_ptr<WorldServer> &server) {
|
|
return server->GetConnection()->GetUUID() == c->GetUUID();
|
|
}
|
|
);
|
|
|
|
if (iter != m_world_servers.end()) {
|
|
LogInfo(
|
|
"World server ID [{}] long_name [{}] short_name [{}] has been disconnected, removing.",
|
|
(*iter)->GetServerId(),
|
|
(*iter)->GetServerLongName(),
|
|
(*iter)->GetServerShortName()
|
|
);
|
|
m_world_servers.erase(iter);
|
|
}
|
|
}
|
|
);
|
|
|
|
}
|
|
|
|
WorldServerManager::~WorldServerManager() = default;
|
|
|
|
std::unique_ptr<EQApplicationPacket> WorldServerManager::CreateServerListPacket(Client *client, uint32 sequence)
|
|
{
|
|
unsigned int server_count = 0;
|
|
in_addr in{};
|
|
in.s_addr = client->GetConnection()->GetRemoteIP();
|
|
std::string client_ip = inet_ntoa(in);
|
|
|
|
LogDebug("ServerManager::CreateServerListPacket via client address [{}]", client_ip);
|
|
|
|
for (const auto &world_server: m_world_servers) {
|
|
if (world_server->IsAuthorizedToList()) {
|
|
++server_count;
|
|
}
|
|
}
|
|
|
|
SerializeBuffer buf;
|
|
|
|
// LoginBaseMessage_Struct header
|
|
buf.WriteInt32(sequence);
|
|
buf.WriteInt8(0);
|
|
buf.WriteInt8(0);
|
|
buf.WriteInt32(0);
|
|
|
|
// LoginBaseReplyMessage_Struct
|
|
buf.WriteInt8(true); // success (no error)
|
|
buf.WriteInt32(0x65); // 101 "No Error" eqlsstr
|
|
buf.WriteString("");
|
|
|
|
// ServerListReply_Struct
|
|
buf.WriteInt32(server_count);
|
|
|
|
for (const auto &s: m_world_servers) {
|
|
if (!s->IsAuthorizedToList()) {
|
|
LogDebug(
|
|
"ServerManager::CreateServerListPacket | Server [{}] via IP [{}] is not authorized to be listed",
|
|
s->GetServerLongName(),
|
|
s->GetConnection()->Handle()->RemoteIP()
|
|
);
|
|
continue;
|
|
}
|
|
|
|
bool use_local_ip = false;
|
|
|
|
std::string world_ip = s->GetConnection()->Handle()->RemoteIP();
|
|
if (world_ip == client_ip || IpUtil::IsIpInPrivateRfc1918(client_ip)) {
|
|
use_local_ip = true;
|
|
}
|
|
|
|
LogDebug(
|
|
"CreateServerListPacket | Building list entry | Client [{}] IP [{}] Server Long Name [{}] Server IP [{}] ({})",
|
|
client->GetAccountName(),
|
|
client_ip,
|
|
s->GetServerLongName(),
|
|
use_local_ip ? s->GetLocalIP() : s->GetRemoteIP(),
|
|
use_local_ip ? "Local" : "Remote"
|
|
);
|
|
|
|
s->SerializeForClientServerList(buf, use_local_ip, client->GetClientVersion());
|
|
}
|
|
|
|
return std::make_unique<EQApplicationPacket>(OP_ServerListResponse, buf);
|
|
}
|
|
|
|
void WorldServerManager::SendUserLoginToWorldRequest(
|
|
unsigned int server_id,
|
|
unsigned int client_account_id,
|
|
const std::string &client_loginserver
|
|
)
|
|
{
|
|
auto iter = std::find_if(
|
|
m_world_servers.begin(), m_world_servers.end(),
|
|
[&](const std::unique_ptr<WorldServer> &server) {
|
|
return server->GetServerId() == server_id;
|
|
}
|
|
);
|
|
|
|
if (iter != m_world_servers.end()) {
|
|
EQ::Net::DynamicPacket outapp;
|
|
outapp.Resize(sizeof(UsertoWorldRequest_Struct));
|
|
|
|
auto *r = reinterpret_cast<UsertoWorldRequest_Struct *>(outapp.Data());
|
|
r->worldid = server_id;
|
|
r->lsaccountid = client_account_id;
|
|
strncpy(r->login, client_loginserver.c_str(), 64);
|
|
|
|
(*iter)->GetConnection()->Send(ServerOP_UsertoWorldReq, outapp);
|
|
|
|
LogNetcode("[UsertoWorldRequest] [Size: {}]\n{}", outapp.Length(), outapp.ToString());
|
|
}
|
|
else {
|
|
LogError("Client requested a user to world but supplied an invalid id of {}", server_id);
|
|
}
|
|
}
|
|
|
|
bool WorldServerManager::DoesServerExist(
|
|
const std::string &server_long_name,
|
|
const std::string &server_short_name,
|
|
WorldServer *ignore
|
|
)
|
|
{
|
|
return std::any_of(
|
|
m_world_servers.begin(), m_world_servers.end(), [&](const std::unique_ptr<WorldServer> &s) {
|
|
return s.get() != ignore &&
|
|
s->GetServerLongName() == server_long_name &&
|
|
s->GetServerShortName() == server_short_name;
|
|
}
|
|
);
|
|
}
|
|
|
|
void WorldServerManager::DestroyServerByName(
|
|
std::string server_long_name,
|
|
std::string server_short_name,
|
|
WorldServer *ignore
|
|
)
|
|
{
|
|
std::erase_if(
|
|
m_world_servers, [&](const std::unique_ptr<WorldServer> &s) {
|
|
if (s.get() == ignore) {
|
|
return false;
|
|
}
|
|
if (s->GetServerLongName() == server_long_name &&
|
|
s->GetServerShortName() == server_short_name) {
|
|
s->GetConnection()->Handle()->Disconnect();
|
|
LogInfo(
|
|
"Removing world server ID [{}] long name [{}] short name [{}]",
|
|
s->GetServerId(),
|
|
server_long_name,
|
|
server_short_name
|
|
);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
);
|
|
}
|
|
|
|
const std::list<std::unique_ptr<WorldServer>> &WorldServerManager::GetWorldServers() const
|
|
{
|
|
return m_world_servers;
|
|
}
|