Rework Clientlist::Process to not skip clients ...

This commit is contained in:
Michael Cook (mackal) 2016-05-16 23:22:42 -04:00
parent d2888e6cca
commit 52bee3e8a0

View File

@ -572,46 +572,37 @@ void Clientlist::CheckForStaleConnections(Client *c) {
} }
} }
void Clientlist::Process() { void Clientlist::Process()
{
std::shared_ptr<EQStream> eqs; std::shared_ptr<EQStream> eqs;
while((eqs = chatsf->Pop())) { while ((eqs = chatsf->Pop())) {
struct in_addr in; struct in_addr in;
in.s_addr = eqs->GetRemoteIP(); in.s_addr = eqs->GetRemoteIP();
Log.Out(Logs::Detail, Logs::UCS_Server, "New Client UDP connection from %s:%d", inet_ntoa(in), ntohs(eqs->GetRemotePort())); Log.Out(Logs::Detail, Logs::UCS_Server, "New Client UDP connection from %s:%d", inet_ntoa(in),
ntohs(eqs->GetRemotePort()));
eqs->SetOpcodeManager(&ChatOpMgr); eqs->SetOpcodeManager(&ChatOpMgr);
auto c = new Client(eqs); auto c = new Client(eqs);
ClientChatConnections.push_back(c); ClientChatConnections.push_back(c);
} }
std::list<Client*>::iterator Iterator; auto it = ClientChatConnections.begin();
while (it != ClientChatConnections.end()) {
for(Iterator = ClientChatConnections.begin(); Iterator != ClientChatConnections.end(); ++Iterator) { (*it)->AccountUpdate();
if ((*it)->ClientStream->CheckClosed()) {
(*Iterator)->AccountUpdate();
if((*Iterator)->ClientStream->CheckClosed()) {
struct in_addr in; struct in_addr in;
in.s_addr = (*it)->ClientStream->GetRemoteIP();
in.s_addr = (*Iterator)->ClientStream->GetRemoteIP();
Log.Out(Logs::Detail, Logs::UCS_Server, "Client connection from %s:%d closed.", inet_ntoa(in), Log.Out(Logs::Detail, Logs::UCS_Server, "Client connection from %s:%d closed.", inet_ntoa(in),
ntohs((*Iterator)->ClientStream->GetRemotePort())); ntohs((*it)->ClientStream->GetRemotePort()));
safe_delete((*Iterator)); safe_delete((*it));
Iterator = ClientChatConnections.erase(Iterator);
if(Iterator == ClientChatConnections.end())
break;
it = ClientChatConnections.erase(it);
continue; continue;
} }
@ -619,114 +610,94 @@ void Clientlist::Process() {
bool KeyValid = true; bool KeyValid = true;
while( KeyValid && !(*Iterator)->GetForceDisconnect() && while (KeyValid && !(*it)->GetForceDisconnect() && (app = (EQApplicationPacket *)(*it)->ClientStream->PopPacket())) {
(app = (EQApplicationPacket *)(*Iterator)->ClientStream->PopPacket())) {
EmuOpcode opcode = app->GetOpcode(); EmuOpcode opcode = app->GetOpcode();
switch(opcode) { switch (opcode) {
case OP_MailLogin: {
char *PacketBuffer = (char *)app->pBuffer;
char MailBox[64];
char Key[64];
char ConnectionTypeIndicator;
case OP_MailLogin: { VARSTRUCT_DECODE_STRING(MailBox, PacketBuffer);
char *PacketBuffer = (char *)app->pBuffer; if (strlen(PacketBuffer) != 9) {
Log.Out(Logs::Detail, Logs::UCS_Server,
"Mail key is the wrong size. Version of world incompatible with UCS.");
KeyValid = false;
break;
}
ConnectionTypeIndicator = VARSTRUCT_DECODE_TYPE(char, PacketBuffer);
char MailBox[64]; (*it)->SetConnectionType(ConnectionTypeIndicator);
char Key[64]; VARSTRUCT_DECODE_STRING(Key, PacketBuffer);
char ConnectionTypeIndicator; std::string MailBoxString = MailBox, CharacterName;
VARSTRUCT_DECODE_STRING(MailBox, PacketBuffer); // Strip off the SOE.EQ.<shortname>.
//
std::string::size_type LastPeriod = MailBoxString.find_last_of(".");
if(strlen(PacketBuffer) != 9) if (LastPeriod == std::string::npos)
{ CharacterName = MailBoxString;
Log.Out(Logs::Detail, Logs::UCS_Server, "Mail key is the wrong size. Version of world incompatible with UCS."); else
KeyValid = false; CharacterName = MailBoxString.substr(LastPeriod + 1);
break;
}
ConnectionTypeIndicator = VARSTRUCT_DECODE_TYPE(char, PacketBuffer);
(*Iterator)->SetConnectionType(ConnectionTypeIndicator); Log.Out(Logs::Detail, Logs::UCS_Server, "Received login for user %s with key %s",
MailBox, Key);
VARSTRUCT_DECODE_STRING(Key, PacketBuffer);
std::string MailBoxString = MailBox, CharacterName;
// Strip off the SOE.EQ.<shortname>.
//
std::string::size_type LastPeriod = MailBoxString.find_last_of(".");
if(LastPeriod == std::string::npos)
CharacterName = MailBoxString;
else
CharacterName = MailBoxString.substr(LastPeriod + 1);
Log.Out(Logs::Detail, Logs::UCS_Server, "Received login for user %s with key %s", MailBox, Key);
if(!database.VerifyMailKey(CharacterName, (*Iterator)->ClientStream->GetRemoteIP(), Key)) {
Log.Out(Logs::Detail, Logs::UCS_Server, "Chat Key for %s does not match, closing connection.", MailBox);
KeyValid = false;
break;
}
(*Iterator)->SetAccountID(database.FindAccount(CharacterName.c_str(), (*Iterator)));
database.GetAccountStatus((*Iterator));
if((*Iterator)->GetConnectionType() == ConnectionTypeCombined)
(*Iterator)->SendFriends();
(*Iterator)->SendMailBoxes();
CheckForStaleConnections((*Iterator));
if (!database.VerifyMailKey(CharacterName, (*it)->ClientStream->GetRemoteIP(), Key)) {
Log.Out(Logs::Detail, Logs::UCS_Server,
"Chat Key for %s does not match, closing connection.", MailBox);
KeyValid = false;
break; break;
} }
case OP_Mail: { (*it)->SetAccountID(database.FindAccount(CharacterName.c_str(), (*it)));
std::string CommandString = (const char*)app->pBuffer; database.GetAccountStatus((*it));
ProcessOPMailCommand((*Iterator), CommandString); if ((*it)->GetConnectionType() == ConnectionTypeCombined)
(*it)->SendFriends();
break; (*it)->SendMailBoxes();
}
default: { CheckForStaleConnections((*it));
break;
}
Log.Out(Logs::Detail, Logs::UCS_Server, "Unhandled chat opcode %8X", opcode); case OP_Mail: {
break; std::string CommandString = (const char *)app->pBuffer;
} ProcessOPMailCommand((*it), CommandString);
break;
}
default: {
Log.Out(Logs::Detail, Logs::UCS_Server, "Unhandled chat opcode %8X", opcode);
break;
}
} }
safe_delete(app); safe_delete(app);
} }
if(!KeyValid || (*Iterator)->GetForceDisconnect()) { if (!KeyValid || (*it)->GetForceDisconnect()) {
struct in_addr in; struct in_addr in;
in.s_addr = (*it)->ClientStream->GetRemoteIP();
in.s_addr = (*Iterator)->ClientStream->GetRemoteIP(); Log.Out(Logs::Detail, Logs::UCS_Server,
"Force disconnecting client: %s:%d, KeyValid=%i, GetForceDisconnect()=%i",
inet_ntoa(in), ntohs((*it)->ClientStream->GetRemotePort()), KeyValid,
(*it)->GetForceDisconnect());
Log.Out(Logs::Detail, Logs::UCS_Server, "Force disconnecting client: %s:%d, KeyValid=%i, GetForceDisconnect()=%i", (*it)->ClientStream->Close();
inet_ntoa(in), ntohs((*Iterator)->ClientStream->GetRemotePort()),
KeyValid, (*Iterator)->GetForceDisconnect());
(*Iterator)->ClientStream->Close(); safe_delete((*it));
safe_delete((*Iterator)); it = ClientChatConnections.erase(it);
Iterator = ClientChatConnections.erase(Iterator);
if(Iterator == ClientChatConnections.end())
break;
} }
++it;
} }
} }
void Clientlist::ProcessOPMailCommand(Client *c, std::string CommandString) void Clientlist::ProcessOPMailCommand(Client *c, std::string CommandString)