void WorldConnection::OnStatusChangeActive(std::shared_ptr<EQ::Net::DaybreakConnection> conn, EQ::Net::DbProtocolStatus from, EQ::Net::DbProtocolStatus to) { if (to == EQ::Net::StatusConnected) { Log.OutF(Logs::General, Logs::Headless_Client, "World connected."); SendClientAuth(); } if (to == EQ::Net::StatusDisconnected) { Log.OutF(Logs::General, Logs::Headless_Client, "World connection lost, reconnecting."); m_connection.reset(); m_connection_manager->Connect(m_host, 9000); } }
bool WorldServer::Process() { ServerPacket *app = nullptr; while(app = connection->PopPacket()) { server_log->WorldTrace("Application packet received from server: 0x%.4X, (size %u)", app->opcode, app->size); if (server_log->DumpIn()) { DumpPacket(app); } switch(app->opcode) { case ServerOP_NewLSInfo: { if(app->size < sizeof(ServerNewLSInfo_Struct)) { server_log->Log(log_network_error, "Received application packet from server that had opcode ServerOP_NewLSInfo, " "but was too small. Discarded to avoid buffer overrun."); break; } server_log->WorldTrace("New Login Info Received."); ServerNewLSInfo_Struct *info = (ServerNewLSInfo_Struct*)app->pBuffer; Handle_NewLSInfo(info); break; } case ServerOP_LSStatus: { if(app->size < sizeof(ServerLSStatus_Struct)) { server_log->Log(log_network_error, "Received application packet from server that had opcode ServerOP_LSStatus, " "but was too small. Discarded to avoid buffer overrun."); break; } server_log->WorldTrace("World Server Status Received."); ServerLSStatus_Struct *ls_status = (ServerLSStatus_Struct*)app->pBuffer; Handle_LSStatus(ls_status); break; } case ServerOP_LSZoneInfo: case ServerOP_LSZoneShutdown: case ServerOP_LSZoneStart: case ServerOP_LSZoneBoot: case ServerOP_LSZoneSleep: case ServerOP_LSPlayerLeftWorld: case ServerOP_LSPlayerJoinWorld: case ServerOP_LSPlayerZoneChange: { //Not logging these to cut down on spam until we implement them break; } case ServerOP_UsertoWorldResp: { if(app->size < sizeof(UsertoWorldResponse_Struct)) { server_log->Log(log_network_error, "Received application packet from server that had opcode ServerOP_UsertoWorldResp, " "but was too small. Discarded to avoid buffer overrun."); break; } //I don't use world trace for this and here is why: //Because this is a part of the client login procedure it makes tracking client errors //While keeping world server spam with multiple servers connected almost impossible. server_log->Trace("User-To-World Response received."); UsertoWorldResponse_Struct *utwr = (UsertoWorldResponse_Struct*)app->pBuffer; server_log->Log(log_client, "Trying to find client with user id of %u.", utwr->lsaccountid); Client *c = server.CM->GetClient(utwr->lsaccountid); if(c && c->GetClientVersion() == cv_old) { if(utwr->response > 0) { SendClientAuth(c->GetConnection()->GetRemoteIP(), c->GetAccountName(), c->GetKey(), c->GetAccountID(), c->GetMacClientVersion()); } switch(utwr->response) { case 1: break; case 0: c->FatalError("\nError 1020: Your chosen World Server is DOWN.\n\nPlease select another."); break; case -1: c->FatalError("You have been suspended from the worldserver."); break; case -2: c->FatalError("You have been banned from the worldserver."); break; case -3: c->FatalError("That server is full."); break; case -4: c->FatalError("Error 1018: You currently have an active character on that EverQuest Server, please allow a minute for synchronization and try again."); break; case -5: c->FatalError("Error IP Limit Exceeded: \n\nYou have exceeded the maximum number of allowed IP addresses for this account."); break; } server_log->Log(log_client, "Found client with user id of %u and account name of %s.", utwr->lsaccountid, c->GetAccountName().c_str()); EQApplicationPacket *outapp = new EQApplicationPacket(OP_PlayEverquestRequest, 17); strncpy((char*) &outapp->pBuffer[1], c->GetKey().c_str(), c->GetKey().size()); c->SendPlayResponse(outapp); } else if(c) { server_log->Log(log_client, "Found client with user id of %u and account name of %s.", utwr->lsaccountid, c->GetAccountName().c_str()); EQApplicationPacket *outapp = new EQApplicationPacket(OP_PlayEverquestResponse, sizeof(PlayEverquestResponse_Struct)); PlayEverquestResponse_Struct *per = (PlayEverquestResponse_Struct*)outapp->pBuffer; per->Sequence = c->GetPlaySequence(); per->ServerNumber = c->GetPlayServerID(); server_log->Log(log_client, "Found sequence and play of %u %u", c->GetPlaySequence(), c->GetPlayServerID()); server_log->LogPacket(log_network_trace, (const char*)outapp->pBuffer, outapp->size); if (utwr->response > 0) { per->Allowed = 1; SendClientAuth(c->GetConnection()->GetRemoteIP(), c->GetAccountName(), c->GetKey(), c->GetAccountID()); } switch (utwr->response) { case 1: per->Message = 101; break; case 0: per->Message = 326; break; case -1: per->Message = 337; break; case -2: per->Message = 338; break; case -3: per->Message = 303; break; case -4: per->Message = 111; break; case -5: per->Message = 198; break; } server_log->Trace("Sending play response to client."); server_log->TracePacket((const char*)outapp->pBuffer, outapp->size); if (server_log->DumpOut()) { DumpPacket(outapp); } c->SendPlayResponse(outapp); delete outapp; } else { server_log->Log(log_client_error, "Received User-To-World Response for %u but could not find the client referenced!.", utwr->lsaccountid); } break; } case ServerOP_LSAccountUpdate: { if(app->size < sizeof(ServerLSAccountUpdate_Struct)) { server_log->Log(log_network_error, "Received application packet from server that had opcode ServerLSAccountUpdate_Struct, " "but was too small. Discarded to avoid buffer overrun."); break; } server_log->Log(log_network_trace, "ServerOP_LSAccountUpdate packet received from: %s", short_name.c_str()); ServerLSAccountUpdate_Struct *lsau = (ServerLSAccountUpdate_Struct*)app->pBuffer; if(trusted) { server_log->Log(log_network_trace, "ServerOP_LSAccountUpdate update processed for: %s", lsau->useraccount); string name; string password; string email; name.assign(lsau->useraccount); password.assign(lsau->userpassword); email.assign(lsau->useremail); db.CreateLSAccount(name, password, email, 0, "", ""); } break; } default: { server_log->Log(log_network_error, "Received application packet from server that had an unknown operation code 0x%.4X.", app->opcode); } } delete app; app = nullptr; } return true; }
bool WorldServer::Process() { ServerPacket *app = nullptr; while(app = connection->PopPacket()) { if(server.options.IsWorldTraceOn()) { server_log->Log(log_network_trace, "Application packet received from server: 0x%.4X, (size %u)", app->opcode, app->size); } if(server.options.IsDumpInPacketsOn()) { DumpPacket(app); } switch(app->opcode) { case ServerOP_NewLSInfo: { if(app->size < sizeof(ServerNewLSInfo_Struct)) { server_log->Log(log_network_error, "Received application packet from server that had opcode ServerOP_NewLSInfo, " "but was too small. Discarded to avoid buffer overrun."); break; } if(server.options.IsWorldTraceOn()) { server_log->Log(log_network_trace, "New Login Info Recieved."); } ServerNewLSInfo_Struct *info = (ServerNewLSInfo_Struct*)app->pBuffer; Handle_NewLSInfo(info); break; } case ServerOP_LSStatus: { if(app->size < sizeof(ServerLSStatus_Struct)) { server_log->Log(log_network_error, "Recieved application packet from server that had opcode ServerOP_LSStatus, " "but was too small. Discarded to avoid buffer overrun."); break; } if(server.options.IsWorldTraceOn()) { server_log->Log(log_network_trace, "World Server Status Recieved."); } ServerLSStatus_Struct *ls_status = (ServerLSStatus_Struct*)app->pBuffer; Handle_LSStatus(ls_status); break; } case ServerOP_LSZoneInfo: case ServerOP_LSZoneShutdown: case ServerOP_LSZoneStart: case ServerOP_LSZoneBoot: case ServerOP_LSZoneSleep: case ServerOP_LSPlayerLeftWorld: case ServerOP_LSPlayerJoinWorld: case ServerOP_LSPlayerZoneChange: { //Not logging these to cut down on spam until we implement them break; } case ServerOP_UsertoWorldResp: { if(app->size < sizeof(UsertoWorldResponse_Struct)) { server_log->Log(log_network_error, "Recieved application packet from server that had opcode ServerOP_UsertoWorldResp, " "but was too small. Discarded to avoid buffer overrun."); break; } //I don't use world trace for this and here is why: //Because this is a part of the client login procedure it makes tracking client errors //While keeping world server spam with multiple servers connected almost impossible. if(server.options.IsTraceOn()) { server_log->Log(log_network_trace, "User-To-World Response received."); } UsertoWorldResponse_Struct *utwr = (UsertoWorldResponse_Struct*)app->pBuffer; server_log->Log(log_client, "Trying to find client with user id of %u.", utwr->lsaccountid); Client *c = server.CM->GetClient(utwr->lsaccountid); if(c) { server_log->Log(log_client, "Found client with user id of %u and account name of %s.", utwr->lsaccountid, c->GetAccountName().c_str()); EQApplicationPacket *outapp = new EQApplicationPacket(OP_PlayEverquestResponse, sizeof(PlayEverquestResponse_Struct)); PlayEverquestResponse_Struct *per = (PlayEverquestResponse_Struct*)outapp->pBuffer; per->Sequence = c->GetPlaySequence(); per->ServerNumber = c->GetPlayServerID(); server_log->Log(log_client, "Found sequence and play of %u %u", c->GetPlaySequence(), c->GetPlayServerID()); server_log->LogPacket(log_network_trace, (const char*)outapp->pBuffer, outapp->size); if(utwr->response > 0) { per->Allowed = 1; SendClientAuth(c->GetConnection()->GetRemoteIP(), c->GetAccountName(), c->GetKey(), c->GetAccountID()); } switch(utwr->response) { case 1: per->Message = 101; break; case 0: per->Message = 326; break; case -1: per->Message = 337; break; case -2: per->Message = 338; break; case -3: per->Message = 303; break; } if(server.options.IsTraceOn()) { server_log->Log(log_network_trace, "Sending play response with following data, allowed %u, sequence %u, server number %u, message %u", per->Allowed, per->Sequence, per->ServerNumber, per->Message); server_log->LogPacket(log_network_trace, (const char*)outapp->pBuffer, outapp->size); } if(server.options.IsDumpOutPacketsOn()) { DumpPacket(outapp); } c->SendPlayResponse(outapp); delete outapp; } else { server_log->Log(log_client_error, "Recieved User-To-World Response for %u but could not find the client referenced!.", utwr->lsaccountid); } break; } case ServerOP_LSAccountUpdate: { server_log->Log(log_network_trace, "ServerOP_LSAccountUpdate packet received from: %s", short_name.c_str()); ServerLSAccountUpdate_Struct *lsau = (ServerLSAccountUpdate_Struct*)app->pBuffer; if(trusted) { server_log->Log(log_network_trace, "ServerOP_LSAccountUpdate update processed for: %s", lsau->useraccount); string name; string password; string email; name.assign(lsau->useraccount); password.assign(lsau->userpassword); email.assign(lsau->useremail); server.db->UpdateLSAccountInfo(lsau->useraccountid, name, password, email); } break; } default: { server_log->Log(log_network_error, "Recieved application packet from server that had an unknown operation code 0x%.4X.", app->opcode); } } delete app; app = nullptr; } return true; }