mirror of
https://github.com/EQEmu/Server.git
synced 2026-06-17 14:58:21 +00:00
[Loginserver] Identify unknown login client packet fields (#1680)
* Add player login reply struct * Use player login reply struct for failed logins * Use base message struct for login requests * Refactor server list reply serialization Use BaseMessage and BaseReplyMessage structs for server list and add flags for server type and status * Use reply message struct for login handshake Remove client version checks, the packets are the same for titanium and rof2 * Use base headers for join server requests * Log correct server list ip * Add compressed flag to base message header Document encrypt type flag more
This commit is contained in:
+45
-130
@@ -97,9 +97,8 @@ WorldServer *ServerManager::GetServerByAddress(const std::string &ip_address, in
|
||||
* @param sequence
|
||||
* @return
|
||||
*/
|
||||
EQApplicationPacket *ServerManager::CreateServerListPacket(Client *client, uint32 sequence)
|
||||
std::unique_ptr<EQApplicationPacket> ServerManager::CreateServerListPacket(Client *client, uint32 sequence)
|
||||
{
|
||||
unsigned int packet_size = sizeof(ServerListHeader_Struct);
|
||||
unsigned int server_count = 0;
|
||||
in_addr in{};
|
||||
in.s_addr = client->GetConnection()->GetRemoteIP();
|
||||
@@ -107,144 +106,60 @@ EQApplicationPacket *ServerManager::CreateServerListPacket(Client *client, uint3
|
||||
|
||||
LogDebug("ServerManager::CreateServerListPacket via client address [{0}]", client_ip);
|
||||
|
||||
auto iter = m_world_servers.begin();
|
||||
while (iter != m_world_servers.end()) {
|
||||
if (!(*iter)->IsAuthorized()) {
|
||||
for (const auto& world_server : m_world_servers)
|
||||
{
|
||||
if (world_server->IsAuthorized()) {
|
||||
++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& world_server : m_world_servers)
|
||||
{
|
||||
if (!world_server->IsAuthorized()) {
|
||||
LogDebug(
|
||||
"ServerManager::CreateServerListPacket | Server [{0}] via IP [{1}] is not authorized to be listed",
|
||||
(*iter)->GetServerLongName(),
|
||||
(*iter)->GetConnection()->Handle()->RemoteIP()
|
||||
"ServerManager::CreateServerListPacket | Server [{}] via IP [{}] is not authorized to be listed",
|
||||
world_server->GetServerLongName(),
|
||||
world_server->GetConnection()->Handle()->RemoteIP()
|
||||
);
|
||||
++iter;
|
||||
continue;
|
||||
}
|
||||
|
||||
std::string world_ip = (*iter)->GetConnection()->Handle()->RemoteIP();
|
||||
if (world_ip == client_ip) {
|
||||
packet_size += (*iter)->GetServerLongName().size() + (*iter)->GetLocalIP().size() + 24;
|
||||
bool use_local_ip = false;
|
||||
|
||||
LogDebug(
|
||||
"CreateServerListPacket | Building list entry | Client [{0}] IP [{1}] Server Long Name [{2}] Server IP [{3}] (Local)",
|
||||
client->GetAccountName(),
|
||||
client_ip,
|
||||
(*iter)->GetServerLongName(),
|
||||
(*iter)->GetLocalIP()
|
||||
);
|
||||
}
|
||||
else if (IpUtil::IsIpInPrivateRfc1918(client_ip)) {
|
||||
packet_size += (*iter)->GetServerLongName().size() + (*iter)->GetLocalIP().size() + 24;
|
||||
|
||||
LogDebug(
|
||||
"CreateServerListPacket | Building list entry | Client [{0}] IP [{1}] Server Long Name [{2}] Server IP [{3}] (Local)",
|
||||
client->GetAccountName(),
|
||||
client_ip,
|
||||
(*iter)->GetServerLongName(),
|
||||
(*iter)->GetLocalIP()
|
||||
);
|
||||
}
|
||||
else {
|
||||
packet_size += (*iter)->GetServerLongName().size() + (*iter)->GetRemoteIP().size() + 24;
|
||||
|
||||
LogDebug(
|
||||
"CreateServerListPacket | Building list entry | Client [{0}] IP [{1}] Server Long Name [{2}] Server IP [{3}] (Remote)",
|
||||
client->GetAccountName(),
|
||||
client_ip,
|
||||
(*iter)->GetServerLongName(),
|
||||
(*iter)->GetRemoteIP()
|
||||
);
|
||||
std::string world_ip = world_server->GetConnection()->Handle()->RemoteIP();
|
||||
if (world_ip == client_ip || IpUtil::IsIpInPrivateRfc1918(client_ip)) {
|
||||
use_local_ip = true;
|
||||
}
|
||||
|
||||
server_count++;
|
||||
++iter;
|
||||
LogDebug(
|
||||
"CreateServerListPacket | Building list entry | Client [{}] IP [{}] Server Long Name [{}] Server IP [{}] ({})",
|
||||
client->GetAccountName(),
|
||||
client_ip,
|
||||
world_server->GetServerLongName(),
|
||||
use_local_ip ? world_server->GetLocalIP() : world_server->GetRemoteIP(),
|
||||
use_local_ip ? "Local" : "Remote"
|
||||
);
|
||||
|
||||
world_server->SerializeForClientServerList(buf, use_local_ip);
|
||||
}
|
||||
|
||||
auto *outapp = new EQApplicationPacket(OP_ServerListResponse, packet_size);
|
||||
auto *server_list = (ServerListHeader_Struct *) outapp->pBuffer;
|
||||
|
||||
server_list->Unknown1 = sequence;
|
||||
server_list->Unknown2 = 0x00000000;
|
||||
server_list->Unknown3 = 0x01650000;
|
||||
|
||||
/**
|
||||
* Not sure what this is but it should be noted setting it to
|
||||
* 0xFFFFFFFF crashes the client so: don't do that.
|
||||
*/
|
||||
server_list->Unknown4 = 0x00000000;
|
||||
server_list->NumberOfServers = server_count;
|
||||
|
||||
unsigned char *data_pointer = outapp->pBuffer;
|
||||
data_pointer += sizeof(ServerListHeader_Struct);
|
||||
|
||||
iter = m_world_servers.begin();
|
||||
while (iter != m_world_servers.end()) {
|
||||
if (!(*iter)->IsAuthorized()) {
|
||||
++iter;
|
||||
continue;
|
||||
}
|
||||
|
||||
std::string world_ip = (*iter)->GetConnection()->Handle()->RemoteIP();
|
||||
if (world_ip == client_ip) {
|
||||
memcpy(data_pointer, (*iter)->GetLocalIP().c_str(), (*iter)->GetLocalIP().size());
|
||||
data_pointer += ((*iter)->GetLocalIP().size() + 1);
|
||||
}
|
||||
else if (IpUtil::IsIpInPrivateRfc1918(client_ip)) {
|
||||
memcpy(data_pointer, (*iter)->GetLocalIP().c_str(), (*iter)->GetLocalIP().size());
|
||||
data_pointer += ((*iter)->GetLocalIP().size() + 1);
|
||||
}
|
||||
else {
|
||||
memcpy(data_pointer, (*iter)->GetRemoteIP().c_str(), (*iter)->GetRemoteIP().size());
|
||||
data_pointer += ((*iter)->GetRemoteIP().size() + 1);
|
||||
}
|
||||
|
||||
switch ((*iter)->GetServerListID()) {
|
||||
case 1: {
|
||||
*(unsigned int *) data_pointer = 0x00000030;
|
||||
break;
|
||||
}
|
||||
case 2: {
|
||||
*(unsigned int *) data_pointer = 0x00000009;
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
*(unsigned int *) data_pointer = 0x00000001;
|
||||
}
|
||||
}
|
||||
|
||||
data_pointer += 4;
|
||||
|
||||
*(unsigned int *) data_pointer = (*iter)->GetServerId();
|
||||
data_pointer += 4;
|
||||
|
||||
memcpy(data_pointer, (*iter)->GetServerLongName().c_str(), (*iter)->GetServerLongName().size());
|
||||
data_pointer += ((*iter)->GetServerLongName().size() + 1);
|
||||
|
||||
memcpy(data_pointer, "EN", 2);
|
||||
data_pointer += 3;
|
||||
|
||||
memcpy(data_pointer, "US", 2);
|
||||
data_pointer += 3;
|
||||
|
||||
// 0 = Up, 1 = Down, 2 = Up, 3 = down, 4 = locked, 5 = locked(down)
|
||||
if ((*iter)->GetStatus() < 0) {
|
||||
if ((*iter)->GetZonesBooted() == 0) {
|
||||
*(uint32 *) data_pointer = 0x01;
|
||||
}
|
||||
else {
|
||||
*(uint32 *) data_pointer = 0x04;
|
||||
}
|
||||
}
|
||||
else {
|
||||
*(uint32 *) data_pointer = 0x02;
|
||||
}
|
||||
data_pointer += 4;
|
||||
|
||||
*(uint32 *) data_pointer = (*iter)->GetPlayersOnline();
|
||||
data_pointer += 4;
|
||||
|
||||
++iter;
|
||||
}
|
||||
|
||||
return outapp;
|
||||
return std::make_unique<EQApplicationPacket>(OP_ServerListResponse, buf);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user