void ClientManager::Process() { ProcessDisconnect(); EQStream *cur = titanium_stream->Pop(); while(cur) { struct in_addr in; in.s_addr = cur->GetRemoteIP(); server_log->Log(log_network, "New Titanium client connection from %s:%d", inet_ntoa(in), ntohs(cur->GetRemotePort())); cur->SetOpcodeManager(&titanium_ops); Client *c = new Client(cur, cv_titanium); clients.push_back(c); cur = titanium_stream->Pop(); } cur = sod_stream->Pop(); while(cur) { struct in_addr in; in.s_addr = cur->GetRemoteIP(); server_log->Log(log_network, "New SoD client connection from %s:%d", inet_ntoa(in), ntohs(cur->GetRemotePort())); cur->SetOpcodeManager(&sod_ops); Client *c = new Client(cur, cv_sod); clients.push_back(c); cur = sod_stream->Pop(); } list<Client*>::iterator iter = clients.begin(); while(iter != clients.end()) { if((*iter)->Process() == false) { server_log->Log(log_client, "Client had a fatal error and had to be removed from the login."); delete (*iter); iter = clients.erase(iter); } else { iter++; } } }
void Clientlist::Process() { EQStream *eqs; while((eqs = mailsf->Pop())) { struct in_addr in; in.s_addr = eqs->GetRemoteIP(); _log(MAIL__CLIENT, "New Client UDP Mail connection from %s:%d", inet_ntoa(in), ntohs(eqs->GetRemotePort())); eqs->SetOpcodeManager(&MailOpMgr); Client *c = new Client(eqs); ClientMailConnections.push_back(c); } list<Client*>::iterator Iterator; for(Iterator = ClientMailConnections.begin(); Iterator != ClientMailConnections.end(); Iterator++) { if((*Iterator)->ClientStream->CheckClosed()) { struct in_addr in; in.s_addr = (*Iterator)->ClientStream->GetRemoteIP(); _log(MAIL__CLIENT, "Client connection from %s:%d closed.", inet_ntoa(in), ntohs((*Iterator)->ClientStream->GetRemotePort())); safe_delete((*Iterator)); Iterator = ClientMailConnections.erase(Iterator); if(Iterator == ClientMailConnections.end()) break; continue; } EQApplicationPacket *app = 0; bool KeyValid = true; while( KeyValid && (app = (EQApplicationPacket *)(*Iterator)->ClientStream->PopPacket())) { _pkt(MAIL__PACKETS, app); EmuOpcode opcode = app->GetOpcode(); switch(opcode) { case OP_MailLogin: { char *PacketBuffer = (char *)app->pBuffer; char MailBox[64]; char Key[64]; VARSTRUCT_DECODE_STRING(MailBox, PacketBuffer); // Check to see if we are running with a version of world that inserts a Connection Type // indicator at the start of the mailkey, and skip past it if so. if(strlen(PacketBuffer) == 9) PacketBuffer++; VARSTRUCT_DECODE_STRING(Key, PacketBuffer); string MailBoxString = MailBox, CharacterName; // Strip off the SOE.EQ.<shortname>. // string::size_type LastPeriod = MailBoxString.find_last_of("."); if(LastPeriod == string::npos) CharacterName = MailBoxString; else CharacterName = MailBoxString.substr(LastPeriod + 1); _log(MAIL__TRACE, "Received login for mailbox %s with key %s", MailBox, Key); if(!database.VerifyMailKey(CharacterName, (*Iterator)->ClientStream->GetRemoteIP(), Key)) { _log(MAIL__ERROR, "Mail Key for %s does not match, closing connection.", MailBox); KeyValid = false; break; } database.FindAccount(CharacterName.c_str(), (*Iterator)); (*Iterator)->SendMailBoxes(); CheckForStaleConnections((*Iterator)); break; } case OP_Mail: { const char *inbuf = (const char*)app->pBuffer; if((app->size >= 11) && !strncmp(inbuf, "getheaders", 10)) { // getheaders database.SendHeaders((*Iterator)); } else if((app->size >= 8) && !strncmp(inbuf, "getbody", 7)) { string GetBodyCommand = inbuf; database.SendBody((*Iterator), atoi(GetBodyCommand.substr(8).c_str())); } else if((app->size >= 7) && !strncmp(inbuf, "mailto", 6)) { ProcessMailTo((*Iterator), inbuf); } else if((app->size >= 17) && !strncmp(inbuf, "setmessagestatus", 16)) { int MessageNumber; int Status; string SetMessageCommand = inbuf; switch(SetMessageCommand[17]) { case 'R': // READ Status = 3; break; case 'T': // TRASH Status = 4; break; default: // DELETE Status = 0; } string::size_type NumStart = SetMessageCommand.find_first_of("123456789", 18); while(NumStart != string::npos) { string::size_type NumEnd = SetMessageCommand.find_first_of(" ", NumStart); if(NumEnd == string::npos) { MessageNumber = atoi(SetMessageCommand.substr(NumStart).c_str()); database.SetMessageStatus(MessageNumber, Status); break; } MessageNumber = atoi(SetMessageCommand.substr(NumStart, NumEnd-NumStart).c_str()); database.SetMessageStatus(MessageNumber, Status); NumStart = SetMessageCommand.find_first_of("123456789", NumEnd); } } else if((app->size >= 14) && !strncmp(inbuf, "selectmailbox", 13)) { string SelectMailBoxCommand = inbuf; string::size_type NumStart = SelectMailBoxCommand.find_first_of("0123456789", 13); int MailBoxNumber = atoi(SelectMailBoxCommand.substr(NumStart).c_str()); _log(MAIL__TRACE, "%s Change to mailbox %i", (*Iterator)->MailBoxName().c_str(), MailBoxNumber); (*Iterator)->SetMailBox(MailBoxNumber); _log(MAIL__TRACE, "New mailbox is %s", (*Iterator)->MailBoxName().c_str()); EQApplicationPacket *outapp = new EQApplicationPacket(OP_MailboxChange, 2); char *buf = (char *)outapp->pBuffer; VARSTRUCT_ENCODE_INTSTRING(buf, MailBoxNumber); _pkt(MAIL__PACKETS, outapp); (*Iterator)->QueuePacket(outapp); safe_delete(outapp); } else if((app->size >= 18) && !strncmp(inbuf, "setmailforwarding", 17)) { // This is sent to turn mail forwarding to your Station email account on/off // Not implemented. _log(MAIL__TRACE, "Unimplemented command: %s", inbuf); } else _log(MAIL__ERROR, "Unhandled OP_Mail command: %s", inbuf); break; } default: { _log(MAIL__ERROR, "Unhandled mail opcode %8X", opcode); break; } } safe_delete(app); } if(!KeyValid) { (*Iterator)->ClientStream->Close(); safe_delete((*Iterator)); Iterator = ClientMailConnections.erase(Iterator); if(Iterator == ClientMailConnections.end()) break; } } }