World <-> Login connection reworked

This commit is contained in:
KimLS
2016-10-28 19:02:03 -07:00
parent fab8765c2f
commit 0b8b41d91f
32 changed files with 729 additions and 701 deletions
+54 -94
View File
@@ -28,91 +28,58 @@ extern bool run_server;
ServerManager::ServerManager()
{
char error_buffer[TCPConnection_ErrorBufferSize];
int listen_port = atoi(server.config->GetVariable("options", "listen_port").c_str());
tcps = new EmuTCPServer(listen_port, true);
if(tcps->Open(listen_port, error_buffer)) {
Log.Out(Logs::General, Logs::Login_Server, "ServerManager listening on port %u", listen_port);
}
else {
Log.Out(Logs::General, Logs::Error, "ServerManager fatal error opening port on %u: %s", listen_port, error_buffer);
run_server = false;
}
server_connection.reset(new EQ::Net::ServertalkServer());
EQ::Net::ServertalkServerOptions opts;
opts.port = listen_port;
opts.ipv6 = false;
server_connection->Listen(opts);
server_connection->OnConnectionIdentified("World", [this](std::shared_ptr<EQ::Net::ServertalkServerConnection> c) {
Log.OutF(Logs::General, Logs::Login_Server, "New world server connection from {0}:{1}", c->Handle()->RemoteIP(), c->Handle()->RemotePort());
WorldServer *server_entity = GetServerByAddress(c->Handle()->RemoteIP(), c->Handle()->RemotePort());
if (server_entity) {
Log.OutF(Logs::General, Logs::Login_Server, "World server already existed for {0}:{1}, removing existing connection and updating current.",
c->Handle()->RemoteIP(), c->Handle()->RemotePort());
server_entity->SetConnection(c);
server_entity->Reset();
}
else {
world_servers.push_back(std::make_unique<WorldServer>(c));
}
});
server_connection->OnConnectionRemoved("World", [this](std::shared_ptr<EQ::Net::ServertalkServerConnection> c) {
auto iter = world_servers.begin();
while (iter != world_servers.end()) {
if ((*iter)->GetConnection()->Handle() == c->Handle()) {
Log.OutF(Logs::General, Logs::World_Server, "World server {0} has been disconnected, removing.", (*iter)->GetLongName().c_str());
world_servers.erase(iter);
return;
}
}
});
}
ServerManager::~ServerManager()
{
if (tcps) {
tcps->Close();
delete tcps;
}
}
void ServerManager::Process()
WorldServer* ServerManager::GetServerByAddress(const std::string &addr, int port)
{
ProcessDisconnect();
EmuTCPConnection *tcp_c = nullptr;
while (tcp_c = tcps->NewQueuePop()) {
in_addr tmp;
tmp.s_addr = tcp_c->GetrIP();
Log.Out(Logs::General, Logs::Login_Server, "New world server connection from %s:%d", inet_ntoa(tmp), tcp_c->GetrPort());
WorldServer *server_entity = GetServerByAddress(tcp_c->GetrIP());
if (server_entity) {
Log.Out(Logs::General, Logs::Login_Server, "World server already existed for %s, removing existing connection and updating current.", inet_ntoa(tmp));
server_entity->GetConnection()->Free();
server_entity->SetConnection(tcp_c);
server_entity->Reset();
}
else {
WorldServer *w = new WorldServer(tcp_c);
world_servers.push_back(w);
}
}
list<WorldServer*>::iterator iter = world_servers.begin();
auto iter = world_servers.begin();
while (iter != world_servers.end()) {
if ((*iter)->Process() == false) {
Log.Out(Logs::General, Logs::World_Server, "World server %s had a fatal error and had to be removed from the login.", (*iter)->GetLongName().c_str());
delete (*iter);
iter = world_servers.erase(iter);
}
else {
++iter;
}
}
}
void ServerManager::ProcessDisconnect()
{
list<WorldServer*>::iterator iter = world_servers.begin();
while (iter != world_servers.end()) {
EmuTCPConnection *connection = (*iter)->GetConnection();
if (!connection->Connected()) {
in_addr tmp;
tmp.s_addr = connection->GetrIP();
Log.Out(Logs::General, Logs::Login_Server, "World server disconnected from the server, removing server and freeing connection.");
connection->Free();
delete (*iter);
iter = world_servers.erase(iter);
}
else {
++iter;
}
}
}
WorldServer* ServerManager::GetServerByAddress(unsigned int address)
{
list<WorldServer*>::iterator iter = world_servers.begin();
while (iter != world_servers.end()) {
if ((*iter)->GetConnection()->GetrIP() == address) {
return (*iter);
if ((*iter)->GetConnection()->Handle()->RemoteIP() == addr && (*iter)->GetConnection()->Handle()->RemotePort()) {
return (*iter).get();
}
++iter;
}
return nullptr;
}
@@ -124,15 +91,14 @@ EQApplicationPacket *ServerManager::CreateServerListPacket(Client *c)
in.s_addr = c->GetConnection()->GetRemoteIP();
string client_ip = inet_ntoa(in);
list<WorldServer*>::iterator iter = world_servers.begin();
auto iter = world_servers.begin();
while (iter != world_servers.end()) {
if ((*iter)->IsAuthorized() == false) {
++iter;
continue;
}
in.s_addr = (*iter)->GetConnection()->GetrIP();
string world_ip = inet_ntoa(in);
std::string world_ip = (*iter)->GetConnection()->Handle()->RemoteIP();
if (world_ip.compare(client_ip) == 0) {
packet_size += (*iter)->GetLongName().size() + (*iter)->GetLocalIP().size() + 24;
@@ -171,8 +137,7 @@ EQApplicationPacket *ServerManager::CreateServerListPacket(Client *c)
continue;
}
in.s_addr = (*iter)->GetConnection()->GetrIP();
string world_ip = inet_ntoa(in);
std::string world_ip = (*iter)->GetConnection()->Handle()->RemoteIP();
if (world_ip.compare(client_ip) == 0) {
memcpy(data_pointer, (*iter)->GetLocalIP().c_str(), (*iter)->GetLocalIP().size());
data_pointer += ((*iter)->GetLocalIP().size() + 1);
@@ -239,21 +204,21 @@ EQApplicationPacket *ServerManager::CreateServerListPacket(Client *c)
void ServerManager::SendUserToWorldRequest(unsigned int server_id, unsigned int client_account_id)
{
list<WorldServer*>::iterator iter = world_servers.begin();
auto iter = world_servers.begin();
bool found = false;
while (iter != world_servers.end()) {
if ((*iter)->GetRuntimeID() == server_id) {
ServerPacket *outapp = new ServerPacket(ServerOP_UsertoWorldReq, sizeof(UsertoWorldRequest_Struct));
UsertoWorldRequest_Struct *utwr = (UsertoWorldRequest_Struct*)outapp->pBuffer;
EQ::Net::WritablePacket outapp;
outapp.Resize(sizeof(UsertoWorldRequest_Struct));
UsertoWorldRequest_Struct *utwr = (UsertoWorldRequest_Struct*)outapp.Data();
utwr->worldid = server_id;
utwr->lsaccountid = client_account_id;
(*iter)->GetConnection()->SendPacket(outapp);
(*iter)->GetConnection()->Send(ServerOP_UsertoWorldReq, outapp);
found = true;
if (server.options.IsDumpInPacketsOn()) {
DumpPacket(outapp);
Log.OutF(Logs::General, Logs::Login_Server, "{0}", outapp.ToString());
}
delete outapp;
}
++iter;
}
@@ -265,9 +230,9 @@ void ServerManager::SendUserToWorldRequest(unsigned int server_id, unsigned int
bool ServerManager::ServerExists(string l_name, string s_name, WorldServer *ignore)
{
list<WorldServer*>::iterator iter = world_servers.begin();
auto iter = world_servers.begin();
while (iter != world_servers.end()) {
if ((*iter) == ignore) {
if ((*iter).get() == ignore) {
++iter;
continue;
}
@@ -283,19 +248,14 @@ bool ServerManager::ServerExists(string l_name, string s_name, WorldServer *igno
void ServerManager::DestroyServerByName(string l_name, string s_name, WorldServer *ignore)
{
list<WorldServer*>::iterator iter = world_servers.begin();
auto iter = world_servers.begin();
while (iter != world_servers.end()) {
if ((*iter) == ignore) {
if ((*iter).get() == ignore) {
++iter;
}
if ((*iter)->GetLongName().compare(l_name) == 0 && (*iter)->GetShortName().compare(s_name) == 0) {
EmuTCPConnection *c = (*iter)->GetConnection();
if (c->Connected()) {
c->Disconnect();
}
c->Free();
delete (*iter);
(*iter)->GetConnection()->Handle()->Disconnect();
iter = world_servers.erase(iter);
}