/* EQ2Emulator: Everquest II Server Emulator Copyright (C) 2007 EQ2EMulator Development Team (http://www.eq2emulator.net) This file is part of EQ2Emulator. */ #include "../common/debug.h" #ifdef WIN32 #define WIN32_LEAN_AND_MEAN #include #include #include #else #include #include #include #include #endif #include #include #include #include #include "net.h" #include "client.h" #include "../common/EQStream.h" #include "../common/packet_dump.h" #include "../common/packet_functions.h" #include "../common/emu_opcodes.h" #include "../common/MiscFunctions.h" #include "LWorld.h" #include "LoginDatabase.h" #include "../common/ConfigReader.h" #include "../common/Log.h" extern NetConnection net; extern LWorldList world_list; extern ClientList client_list; extern LoginDatabase database; extern mapEQOpcodeManager; extern ConfigReader configReader; using namespace std; Client::Client(EQStream* ieqnc) { eqnc = ieqnc; ip = eqnc->GetrIP(); port = ntohs(eqnc->GetrPort()); account_id = 0; lsadmin = 0; worldadmin = 0; lsstatus = 0; origversion = version = 0; kicked = false; verified = false; memset(bannedreason, 0, sizeof(bannedreason)); //worldresponse_timer = new Timer(10000); //worldresponse_timer->Disable(); memset(key,0,10); LoginMode = None; num_updates = 0; updatetimer = new Timer(500); updatelisttimer = new Timer(10000); //keepalive = new Timer(5000); //logintimer = new Timer(500); // Give time for the servers to send updates //keepalive->Start(); //updatetimer->Start(); //logintimer->Disable(); disconnectTimer = 0; memset(ClientSession,0,25); request_num = 0; login_account = 0; createRequest = 0; playWaitTimer = NULL; start = false; update_position = 0; update_packets = 0; needs_world_list = true; } Client::~Client() { //safe_delete(worldresponse_timer); //safe_delete(logintimer); safe_delete(login_account); eqnc->Close(); safe_delete(playWaitTimer); safe_delete(createRequest); safe_delete(disconnectTimer); safe_delete(updatetimer); } bool Client::Process() { if(!start && !eqnc->CheckActive()){ if(!playWaitTimer) playWaitTimer = new Timer(5000); else if(playWaitTimer->Check()){ safe_delete(playWaitTimer); return false; } return true; } else if(!start){ safe_delete(playWaitTimer); start = true; } //if(disconnectTimer && disconnectTimer->Check()) // getConnection()->SendDisconnect(); if (!kicked) { /************ Get all packets from packet manager out queue and process them ************/ EQApplicationPacket *app = 0; /*if(logintimer && logintimer->Check()) { database.LoadCharacters(GetLoginAccount()); SendLoginAccepted(); logintimer->Disable(); }*/ /*if(worldresponse_timer && worldresponse_timer->Check()) { FatalError(WorldDownErrorMessage); worldresponse_timer->Disable(); }*/ if(playWaitTimer != NULL && playWaitTimer->Check ( ) ) { SendPlayFailed(PLAY_ERROR_SERVER_TIMEOUT); safe_delete(playWaitTimer); } if(!needs_world_list && updatetimer && updatetimer->Check()){ if(updatelisttimer && updatelisttimer->Check()){ if(num_updates >= 180){ //30 minutes getConnection()->SendDisconnect(); } else{ vector::iterator itr; if(update_packets){ for(itr = update_packets->begin(); itr != update_packets->end(); itr++){ safe_delete(*itr); } } safe_delete(update_packets); update_packets = world_list.GetServerListUpdate(version); } num_updates++; } else{ if(!update_packets){ update_packets = world_list.GetServerListUpdate(version); } else{ if(update_position < update_packets->size()){ QueuePacket(update_packets->at(update_position)->serialize()); update_position++; } else update_position = 0; } } } while(app = eqnc->PopPacket()) { switch(app->GetOpcode()) { case OP_LoginRequestMsg:{ // DumpPacket(app); PacketStruct* packet = configReader.getStruct("LS_LoginRequest", 1); if(packet->LoadPacketData(app->pBuffer,app->size)){ version = packet->getType_int32_ByName("version"); LogWrite(LOGIN__DEBUG, 0, "Login", "Client Version Provided: %i", version); // Image 2020 Notes // we keep the original version for special packets like char creation to pass to world server origversion = version; // forced version to 60085 for now since those structures seem to work best for steam AoM 12133L Aug 17 2015 11:19:13 build version = 60085; if (EQOpcodeManager.count(GetOpcodeVersion(version)) == 0) { LogWrite(LOGIN__ERROR, 0, "Login", "Incompatible client version provided: %i", version); SendLoginDenied(); return false; } if(EQOpcodeManager.count(GetOpcodeVersion(version)) > 0 && getConnection()){ getConnection()->SetClientVersion(GetOrigVersion()); EQ2_16BitString username = packet->getType_EQ2_16BitString_ByName("username"); EQ2_16BitString password = packet->getType_EQ2_16BitString_ByName("password"); LoginAccount* acct = database.LoadAccount(username.data.c_str(),password.data.c_str()); if(acct){ Client* otherclient = client_list.FindByLSID(acct->getLoginAccountID()); if(otherclient) otherclient->getConnection()->SendDisconnect(); // This person is already logged in, we don't want them logged in twice, kick the previous client as it might be a ghost } if(acct){ SetAccountName(username.data.c_str()); database.UpdateAccountIPAddress(acct->getLoginAccountID(), getConnection()->GetrIP()); LogWrite(LOGIN__INFO, 0, "Login", "%s successfully logged in.", (char*)username.data.c_str()); } else { if (username.size > 0) LogWrite(LOGIN__ERROR, 0, "Login", "%s login failed!", (char*)username.data.c_str()); else LogWrite(LOGIN__ERROR, 0, "Login", "[UNKNOWN USER] login failed!"); } if(!acct) SendLoginDenied(); else{ needs_world_list = true; SetLoginAccount(acct); SendLoginAccepted(); } } else{ cout << "Error bad version: " << version << endl; SendLoginDeniedBadVersion(); } } else{ cout << "Error loading LS_LoginRequest packet: \n"; //DumpPacket(app); } safe_delete(packet); break; } case OP_KeymapLoadMsg:{ // cout << "Received OP_KeymapNoneMsg\n"; //dunno what this is for break; } case OP_AllWSDescRequestMsg:{ SendWorldList(); needs_world_list = false; database.LoadCharacters(GetLoginAccount(), GetOrigVersion()); SendCharList(); break; } case OP_LsClientCrashlogReplyMsg:{ // DumpPacket(app); SaveErrorsToDB(app, "Crash Log"); break; } case OP_LsClientVerifylogReplyMsg:{ // DumpPacket(app); SaveErrorsToDB(app, "Verify Log"); break; } case OP_LsClientAlertlogReplyMsg:{ // DumpPacket(app); SaveErrorsToDB(app, "Alert Log"); break; } case OP_LsClientBaselogReplyMsg:{ // DumpPacket(app); SaveErrorsToDB(app, "Base Log"); break; } case OP_AllCharactersDescRequestMsg:{ break; } case OP_CreateCharacterRequestMsg:{ PacketStruct* packet = configReader.getStruct("CreateCharacter", GetOrigVersion()); playWaitTimer = new Timer ( 15000 ); playWaitTimer->Start ( ); cout << "Char Create Request From: " << GetAccountName() << "...."; if(packet->LoadPacketData(app->pBuffer,app->size)){ cout << "Loaded Successfully\n"; packet->setDataByName("account_id",GetAccountID()); LWorld* world_server = world_list.FindByID(packet->getType_int32_ByName("server_id")); if(!world_server) { cout << GetAccountName() << " attempted creation of character with an invalid server id of: " << packet->getType_int32_ByName("server_id") << "\n"; break; } else { ServerPacket* outpack = new ServerPacket(ServerOP_CharacterCreate, app->size+sizeof(int16)); int16 out_version = GetOrigVersion(); memcpy(outpack->pBuffer, &out_version, sizeof(int16)); memcpy(outpack->pBuffer + sizeof(int16), app->pBuffer, app->size); uchar* tmp = outpack->pBuffer; tmp+=7; int32 account_id = GetAccountID(); memcpy(tmp, &account_id, sizeof(int32)); world_server->SendPacket(outpack); safe_delete(outpack); createRequest = packet; } } else{ cout << "Error loading Char Create Packet!!\n"; safe_delete(packet); } // world_list.SendWorldChanged(create.profile.server_id, false, this); break; } case OP_PlayCharacterRequestMsg:{ int32 char_id = 0; int32 server_id = 0; PacketStruct* request = configReader.getStruct("LS_PlayRequest",GetVersion()); if(request && request->LoadPacketData(app->pBuffer,app->size)){ char_id = request->getType_int32_ByName("char_id"); server_id = request->getType_int32_ByName("server_id"); LWorld* world = world_list.FindByID(server_id); string name = database.GetCharacterName(char_id,server_id); if(world && name.length() > 0){ pending_play_char_id = char_id; ServerPacket* outpack = new ServerPacket(ServerOP_UsertoWorldReq, sizeof(UsertoWorldRequest_Struct)); UsertoWorldRequest_Struct* req = (UsertoWorldRequest_Struct*)outpack->pBuffer; req->char_id = char_id; req->lsaccountid = GetAccountID(); req->worldid = server_id; struct in_addr in; in.s_addr = GetIP(); strcpy(req->ip_address, inet_ntoa(in)); world->SendPacket(outpack); delete outpack; safe_delete(playWaitTimer); playWaitTimer = new Timer ( 5000 ); playWaitTimer->Start ( ); } else{ cout << GetAccountName() << " sent invalid Play Request: \n"; SendPlayFailed(PLAY_ERROR_PROBLEM); DumpPacket(app); } } safe_delete(request); break; } case OP_DeleteCharacterRequestMsg:{ PacketStruct* request = configReader.getStruct("LS_DeleteCharacterRequest", GetVersion()); PacketStruct* response = configReader.getStruct("LS_DeleteCharacterResponse", GetVersion()); if(request && response && request->LoadPacketData(app->pBuffer,app->size)){ EQ2_16BitString name = request->getType_EQ2_16BitString_ByName("name"); int32 acct_id = GetAccountID(); int32 char_id = request->getType_int32_ByName("char_id"); int32 server_id = request->getType_int32_ByName("server_id"); if(database.VerifyDelete(acct_id, char_id, name.data.c_str())){ response->setDataByName("response", 1); GetLoginAccount()->removeCharacter((char*)name.data.c_str()); LWorld* world_server = world_list.FindByID(server_id); if(world_server != NULL) world_server->SendDeleteCharacter ( char_id , acct_id ); } else response->setDataByName("response", 0); response->setDataByName("server_id", server_id); response->setDataByName("char_id", char_id); response->setDataByName("account_id", account_id); response->setMediumStringByName("name", (char*)name.data.c_str()); response->setDataByName("max_characters", 10); EQ2Packet* outapp = response->serialize(); QueuePacket(outapp); } safe_delete(request); safe_delete(response); break; } default: { char* name = (char*)app->GetOpcodeName(); if(name) cout << name; else cout << "Unknown"; cout << " Packet: OPCode: 0x" << hex << setw(2) << setfill('0') << app->GetOpcode() << dec << ", size: " << setw(5) << setfill(' ') << app->Size() << " from " << GetAccountName() << endl; if (app->Size() < 128) DumpPacket(app); } } delete app; } } if (!eqnc->CheckActive()) { return false; } return true; } void Client::SaveErrorsToDB(EQApplicationPacket* app, char* type){ int32 size = 0; memcpy(&size, app->pBuffer + sizeof(int32), sizeof(int32)); size++; char* message = new char[size]; memset(message, 0, size); z_stream zstream; int zerror = 0; zstream.next_in = app->pBuffer + 8; zstream.avail_in = app->size - 8; zstream.next_out = (BYTE*)message; zstream.avail_out = size; zstream.zalloc = Z_NULL; zstream.zfree = Z_NULL; zstream.opaque = Z_NULL; zerror = inflateInit( &zstream); if(zerror != Z_OK) { safe_delete_array(message); return; } zerror = inflate( &zstream, 0 ); if(message && strlen(message) > 0) database.SaveClientLog(type, message, GetLoginAccount()->getLoginName(), GetVersion()); safe_delete_array(message); } void Client::CharacterApproved(int32 server_id,int32 char_id) { if(createRequest && server_id == createRequest->getType_int32_ByName("server_id")){ LWorld* world_server = world_list.FindByID(server_id); if(!world_server) return; PacketStruct* packet = configReader.getStruct("LS_CreateCharacterReply", GetVersion()); if(packet){ packet->setDataByName("account_id", GetAccountID()); packet->setDataByName("response", CREATESUCCESS_REPLY); packet->setMediumStringByName("name", (char*)createRequest->getType_EQ2_16BitString_ByName("name").data.c_str()); EQ2Packet* outapp = packet->serialize(); QueuePacket(outapp); safe_delete(packet); database.SaveCharacter(createRequest, GetLoginAccount(),char_id); // refresh characters for this account database.LoadCharacters(GetLoginAccount(), GetVersion()); SendCharList(); } } else{ cout << GetAccountName() << " received invalid CharacterApproval from server: " << server_id << endl; } safe_delete(createRequest); } void Client::CharacterRejected(int8 reason_number) { PacketStruct* packet = configReader.getStruct("LS_CreateCharacterReply", GetVersion()); if(createRequest && packet){ packet->setDataByName("account_id", GetAccountID()); int8 clientReasonNum = reason_number; // reason numbers change and instead of updating the world server // the login server will hold the up to date #'s /* switch(reason_number) { // these error codes seem to be removed now, they shutdown the client rather immediately // for now we are just going to play a joke on them and say they can't create a new character. case INVALIDRACE_REPLY: case INVALIDGENDER_REPLY: clientReasonNum = 8; break; case BADNAMELENGTH_REPLY: clientReasonNum = 9; break; case NAMEINVALID_REPLY: clientReasonNum = 10; break; case NAMEFILTER_REPLY: clientReasonNum = 11; break; case NAMETAKEN_REPLY: clientReasonNum = 12; break; case OVERLOADEDSERVER_REPLY: clientReasonNum = 13; break; } */ packet->setDataByName("response", clientReasonNum); packet->setMediumStringByName("name", ""); EQ2Packet* outapp = packet->serialize(); QueuePacket(outapp); safe_delete(packet); } /*LS_CreateCharacterReply reply(GetAccountID(), reason_number, create.profile.name.data); EQ2Packet* outapp = reply.serialize(); QueuePacket(outapp); create.Clear();*/ } void Client::SendCharList(){ /*PacketStruct* packet = configReader.getStruct("LS_CreateCharacterReply"); packet->setDataByName("account_id", GetAccountID()); packet->setDataByName("response", reason_number); packet->setDataByName("name", &create.profile.name); EQ2Packet* outapp = packet->serialize(); QueuePacket(outapp); safe_delete(packet);*/ LogWrite(LOGIN__INFO, 0, "Login", "[%s] sending character list.", GetAccountName()); LS_CharSelectList list; list.loadData(GetAccountID(), GetLoginAccount()->charlist, GetVersion()); EQ2Packet* outapp = list.serialize(GetVersion()); // DumpPacket(outapp); QueuePacket(outapp); } void Client::SendLoginDeniedBadVersion(){ EQ2Packet* app = new EQ2Packet(OP_LoginReplyMsg, 0, sizeof(LS_LoginResponse)); LS_LoginResponse* ls_response = (LS_LoginResponse*)app->pBuffer; ls_response->reply_code = 6; ls_response->unknown03 = 0xFFFFFFFF; ls_response->unknown04 = 0xFFFFFFFF; QueuePacket(app); } void Client::SendLoginDenied(){ EQ2Packet* app = new EQ2Packet(OP_LoginReplyMsg, 0, sizeof(LS_LoginResponse)); LS_LoginResponse* ls_response = (LS_LoginResponse*)app->pBuffer; ls_response->reply_code = 1; ls_response->unknown03 = 0xFFFFFFFF; ls_response->unknown04 = 0xFFFFFFFF; QueuePacket(app); } void Client::SendLoginAccepted(){ //all 0s are a success :) PacketStruct* packet = configReader.getStruct("LS_LoginReplyMsg",version); int i =0; if ( packet ) { packet->setDataByName("account_id", 1); packet->setDataByName("login_response", 0); packet->setDataByName("reset_appearance", 0); packet->setDataByName("do_not_force_soga", 1); packet->setDataByName("race_unknown", 0x3F); packet->setDataByName("unknown11", 2); // can be 7 packet->setDataByName("sub_level", 2); packet->setDataByName("race_flag", 0x1FFFFF); packet->setDataByName("class_flag", 0x7FFFFFE); packet->setMediumStringByName("username", GetAccountName()); packet->setMediumStringByName("password", GetAccountName()); packet->setDataByName("unknown5", 0x7C); packet->setDataByName("unknown7", 0xFF6FFFBF); // Image 2020 Notes // Login Server only supports AoM at current time, but we will need to keep in mind the structure for 60100 or later calls for additional custom fields // >=60100 //packet->setDataByName("unknown7a", 0xFFFF); //packet->setDataByName("unknown8", 0xFF, 1); EQ2Packet* outapp = packet->serialize(); QueuePacket(outapp); safe_delete(packet); } return; if(version >= 843){ uchar login_accepted_packet[] ={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 ,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x7C,0x00,0x00,0xBF,0xBF,0xED,0x03 ,0x1F,0x00,0x00,0x00,0x00,0x01,0x18,0x03,0x05,0x3C,0x02,0x03,0x01,0x00,0xF4,0xF4 ,0xF4,0xFF,0xFF,0xFF,0x3D,0x02,0x08,0x01,0x00,0xF4,0xF4,0xF4,0xFF,0xFF,0xFF,0x41 ,0x02,0x07,0x01,0x00,0xF4,0xF4,0xF4,0xFF,0xFF,0xFF,0xAE,0x0C,0x00,0x00,0x00,0xFF ,0xFF,0xFF,0xFF,0xFF,0xFF,0x34,0x0F,0x10,0x01,0x01,0x93,0x62,0x44,0xCF,0xCF,0xAF ,0x04,0x06,0x3C,0x02,0x03,0x01,0x00,0xB6,0x36,0x36,0xFF,0xFF,0xFF,0x41,0x02,0x07 ,0x01,0x00,0xB6,0x36,0x36,0xFF,0xFF,0xFF,0x3D,0x02,0x08,0x01,0x00,0xB6,0x36,0x36 ,0xFF,0xFF,0xFF,0x0F,0x09,0x00,0x01,0x01,0x67,0x54,0x42,0xA0,0xA0,0x50,0x0F,0x09 ,0x00,0x01,0x01,0x67,0x54,0x42,0xA0,0xA0,0x50,0x34,0x0F,0x10,0x01,0x01,0x93,0x62 ,0x44,0xCF,0xCF,0xAF,0x06,0x06,0x31,0x00,0x00,0x01,0x01,0xF4,0xF4,0xF4,0xF4,0xF4 ,0xF4,0x31,0x00,0x00,0x01,0x01,0xF4,0xF4,0xF4,0xF4,0xF4,0xF4,0xF3,0x02,0x03,0x00 ,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x31,0x00,0x07,0x00,0x00,0xFF,0xFF,0xFF,0xFF ,0xFF,0xFF,0x31,0x00,0x08,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xF8,0x0E,0x10 ,0x01,0x01,0xFF,0xFF,0x00,0x80,0x80,0x00,0x07,0x06,0xE6,0x09,0x00,0x01,0x01,0xBA ,0x7B,0x42,0xBA,0x7B,0x42,0xE6,0x09,0x00,0x01,0x01,0xBA,0x7B,0x42,0xBA,0x7B,0x42 ,0xA6,0x01,0x08,0x01,0x01,0x77,0x60,0x46,0x77,0x60,0x46,0xAA,0x01,0x07,0x01,0x01 ,0x77,0x60,0x46,0x77,0x60,0x46,0xC7,0x0F,0x03,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0xFF ,0xFF,0xB2,0x0C,0x10,0x01,0x01,0xFF,0xFF,0x00,0x80,0x80,0x00,0x09,0x05,0x33,0x02 ,0x03,0x01,0x00,0x2D,0x2D,0x2D,0xFF,0xFF,0xFF,0x34,0x02,0x08,0x01,0x00,0x2D,0x2D ,0x2D,0xFF,0xFF,0xFF,0x38,0x02,0x07,0x01,0x00,0x2D,0x2D,0x2D,0xFF,0xFF,0xFF,0x69 ,0x09,0x00,0x01,0x01,0x6D,0x1C,0x1C,0x93,0x6B,0x6B,0x34,0x0F,0x10,0x01,0x01,0x93 ,0x62,0x44,0xCF,0xCF,0xAF,0x0A,0x05,0x69,0x09,0x00,0x01,0x01,0xA7,0xA7,0xEB,0xA7 ,0xA7,0xEB,0x33,0x02,0x03,0x01,0x00,0xF4,0xF4,0xF4,0xFF,0xFF,0xFF,0x38,0x02,0x07 ,0x01,0x00,0xF4,0xF4,0xF4,0xFF,0xFF,0xFF,0x34,0x02,0x08,0x01,0x00,0xF4,0xF4,0xF4 ,0xFF,0xFF,0xFF,0x34,0x0F,0x10,0x01,0x01,0x93,0x62,0x44,0xCF,0xCF,0xAF,0x0D,0x04 ,0xEA,0x09,0x00,0x01,0x01,0xDD,0xDD,0x8C,0xDD,0xDD,0x8C,0x95,0x02,0x08,0x01,0x00 ,0xF4,0xF4,0x0A,0xFF,0xFF,0xFF,0x94,0x02,0x03,0x01,0x00,0xF4,0xF4,0x0A,0xFF,0xFF ,0xFF,0x99,0x02,0x07,0x01,0x00,0xF4,0xF4,0x0A,0xFF,0xFF,0xFF,0x0E,0x04,0xC6,0x02 ,0x08,0x01,0x00,0x13,0x13,0x13,0xFF,0xFF,0xFF,0xC5,0x02,0x03,0x01,0x00,0x13,0x13 ,0x13,0xFF,0xFF,0xFF,0xCA,0x02,0x07,0x01,0x00,0x13,0x13,0x13,0xFF,0xFF,0xFF,0x14 ,0x09,0x00,0x01,0x01,0x9C,0x4F,0x4F,0x2B,0x15,0x15,0x10,0x04,0xDF,0x09,0x00,0x01 ,0x01,0x70,0xBA,0x70,0xBA,0x7B,0x42,0x38,0x04,0x08,0x01,0x00,0xB6,0xCD,0x2F,0xFF ,0xFF,0xFF,0x37,0x04,0x03,0x01,0x00,0xB6,0xCD,0x2F,0xFF,0xFF,0xFF,0x3C,0x04,0x07 ,0x01,0x00,0xB6,0xCD,0x2F,0xFF,0xFF,0xFF,0x11,0x04,0xDF,0x09,0x00,0x01,0x01,0xBA ,0x7B,0x42,0x62,0xB3,0x62,0x38,0x04,0x08,0x01,0x00,0x1A,0x41,0x1A,0xFF,0xFF,0xFF ,0x3C,0x04,0x07,0x01,0x00,0x1A,0x41,0x1A,0xFF,0xFF,0xFF,0x37,0x04,0x03,0x01,0x00 ,0x1A,0x41,0x1A,0xFF,0xFF,0xFF,0x13,0x04,0x59,0x0E,0x00,0x01,0x01,0x3B,0x7C,0x3B ,0xE2,0xE2,0x85,0xB6,0x03,0x08,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xB5,0x03 ,0x03,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xBA,0x03,0x07,0x00,0x00,0xFF,0xFF ,0xFF,0xFF,0xFF,0xFF,0x14,0x04,0x59,0x0E,0x00,0x01,0x01,0x2B,0x34,0x21,0xE2,0xE2 ,0x85,0xA8,0x03,0x08,0x01,0x01,0x18,0x18,0x18,0x18,0x18,0x18,0xA7,0x03,0x03,0x01 ,0x01,0x18,0x18,0x18,0x18,0x18,0x18,0xAC,0x03,0x07,0x01,0x01,0x18,0x18,0x18,0x18 ,0x18,0x18,0x17,0x04,0x4B,0x0E,0x00,0x01,0x01,0xE6,0x95,0xE6,0xE6,0x95,0xE6,0xDA ,0x01,0x07,0x01,0x01,0x9E,0x9E,0xD8,0xA3,0x6B,0x80,0x92,0x17,0x03,0x01,0x01,0x66 ,0x42,0x4B,0x9E,0x9E,0xD8,0xD6,0x01,0x08,0x01,0x01,0x9E,0x9E,0xD8,0xA3,0x6B,0x80 ,0x18,0x04,0x4D,0x0E,0x00,0x01,0x01,0xCF,0x2F,0xCF,0xE6,0x95,0xE6,0x92,0x17,0x03 ,0x01,0x01,0x70,0x70,0x70,0x67,0x2B,0x67,0xD6,0x01,0x08,0x01,0x01,0x67,0x2B,0x67 ,0x50,0x50,0x50,0xDA,0x01,0x07,0x01,0x01,0x67,0x2B,0x67,0x50,0x50,0x50,0x1A,0x04 ,0xE4,0x0C,0x00,0x01,0x01,0xBA,0xFF,0xBA,0xD4,0xE9,0xFF,0x92,0x17,0x03,0x01,0x01 ,0xDA,0xDA,0xA5,0x60,0x60,0x9E,0xDA,0x01,0x07,0x01,0x01,0x60,0x60,0x9E,0xDA,0xDA ,0xA5,0xD6,0x01,0x08,0x01,0x01,0x60,0x60,0x9E,0xDA,0xDA,0xA5,0x1B,0x04,0x92,0x17 ,0x03,0x01,0x01,0x99,0x48,0x48,0xF7,0xCF,0x82,0xDA,0x01,0x07,0x01,0x01,0xF7,0xCF ,0x82,0x99,0x48,0x48,0xD6,0x01,0x08,0x01,0x01,0xF7,0xCF,0x82,0x99,0x48,0x48,0xD7 ,0x0E,0x00,0x01,0x01,0x8E,0x46,0x46,0x2B,0x15,0x15,0x1D,0x04,0xA9,0x08,0x00,0x01 ,0x01,0xE8,0xB6,0x85,0xE8,0xB6,0x85,0x92,0x17,0x03,0x01,0x01,0x57,0x85,0xAE,0xD8 ,0xE8,0xF4,0xD6,0x01,0x08,0x01,0x01,0xD8,0xE8,0xF4,0x95,0xB3,0xCD,0xDA,0x01,0x07 ,0x01,0x01,0xD8,0xE8,0xF4,0x95,0xB3,0xCD,0x1E,0x04,0x92,0x17,0x03,0x01,0x01,0x62 ,0x57,0x4D,0xA3,0x9E,0x9A,0xD6,0x01,0x08,0x01,0x01,0xFF,0xDA,0xB6,0x6B,0x57,0x44 ,0xDA,0x01,0x07,0x01,0x01,0xFF,0xDA,0xB6,0x6B,0x57,0x44,0x3A,0x0E,0x00,0x01,0x01 ,0x2B,0x54,0x54,0x2B,0x15,0x15,0x21,0x06,0x64,0x03,0x08,0x01,0x00,0x7E,0x4B,0x46 ,0xFF,0xFF,0xFF,0x68,0x03,0x07,0x01,0x00,0x7E,0x4B,0x46,0xFF,0xFF,0xFF,0x63,0x03 ,0x03,0x01,0x00,0x7E,0x4B,0x46,0xFF,0xFF,0xFF,0xA9,0x08,0x00,0x01,0x01,0x1F,0x3F ,0x60,0x62,0x62,0x62,0xA9,0x08,0x00,0x01,0x01,0x1F,0x3F,0x60,0x62,0x62,0x62,0x42 ,0x0F,0x10,0x01,0x01,0xFF,0xFF,0x00,0x80,0x80,0x00,0x22,0x06,0xD6,0x0C,0x00,0x01 ,0x01,0xE6,0x95,0xE6,0x1A,0x1A,0x70,0xD6,0x0C,0x00,0x01,0x01,0xE6,0x95,0xE6,0x1A ,0x1A,0x70,0x64,0x03,0x08,0x01,0x00,0x5D,0x42,0x5D,0xFF,0xFF,0xFF,0x68,0x03,0x07 ,0x01,0x00,0x5D,0x42,0x5D,0xFF,0xFF,0xFF,0x63,0x03,0x03,0x01,0x00,0x5D,0x42,0x5D ,0xFF,0xFF,0xFF,0x42,0x0F,0x10,0x01,0x01,0xFF,0xFF,0x00,0x80,0x80,0x00,0x24,0x06 ,0x63,0x03,0x03,0x01,0x00,0x99,0xC8,0xE2,0xFF,0xFF,0xFF,0x64,0x03,0x08,0x01,0x00 ,0x99,0xC8,0xE2,0xFF,0xFF,0xFF,0x68,0x03,0x07,0x01,0x00,0x99,0xC8,0xE2,0xFF,0xFF ,0xFF,0xD6,0x0C,0x00,0x01,0x01,0x85,0x85,0xA7,0xD1,0xD1,0xAC,0xD6,0x0C,0x00,0x01 ,0x01,0x85,0x85,0xA7,0xD1,0xD1,0xAC,0x34,0x0F,0x10,0x01,0x01,0x93,0x62,0x44,0xCF ,0xCF,0xAF,0x25,0x06,0x63,0x03,0x03,0x01,0x00,0xBF,0xA5,0x7E,0xFF,0xFF,0xFF,0x5C ,0x03,0x08,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x60,0x03,0x07,0x00,0x00,0xFF ,0xFF,0xFF,0xFF,0xFF,0xFF,0xB1,0x08,0x00,0x01,0x01,0x90,0x48,0x48,0x90,0x48,0x48 ,0xB1,0x08,0x00,0x01,0x01,0x90,0x48,0x48,0x90,0x48,0x48,0x34,0x0F,0x10,0x01,0x01 ,0x93,0x62,0x44,0xCF,0xCF,0xAF,0x27,0x06,0xB9,0x16,0x08,0x01,0x01,0x3D,0x54,0x3D ,0xBC,0xBC,0xBC,0xB8,0x16,0x03,0x01,0x01,0x3D,0x54,0x3D,0xBC,0xBC,0xBC,0xBD,0x16 ,0x07,0x01,0x01,0x3D,0x54,0x3D,0xBC,0xBC,0xBC,0x34,0x0F,0x10,0x01,0x01,0x31,0x4D ,0x3F,0xCF,0xCF,0xAF,0xCD,0x08,0x00,0x01,0x01,0x2B,0x54,0x3F,0x3F,0x98,0x6B,0xCD ,0x08,0x00,0x01,0x01,0x2B,0x54,0x3F,0x3F,0x98,0x6B,0x28,0x06,0xB9,0x16,0x08,0x01 ,0x01,0x21,0x21,0x31,0x3F,0x3F,0x3F,0xB8,0x16,0x03,0x01,0x01,0x21,0x21,0x31,0x3F ,0x3F,0x3F,0xBD,0x16,0x07,0x01,0x00,0x48,0x48,0x54,0xFF,0xFF,0xFF,0x34,0x0F,0x10 ,0x01,0x01,0x31,0x4D,0x3F,0xCF,0xCF,0xAF,0xA9,0x08,0x00,0x01,0x01,0x1A,0x1A,0x70 ,0xE6,0x95,0xE6,0xA9,0x08,0x00,0x01,0x01,0x1A,0x1A,0x70,0xE6,0x95,0xE6,0x0A,0xD1 ,0x00,0x00,0x00,0xD0,0x00,0x00,0x00,0xCF,0x00,0x00,0x00,0x6E,0x00,0x00,0x00,0x70 ,0x00,0x00,0x00,0x71,0x00,0x00,0x00,0x72,0x00,0x00,0x00,0x73,0x00,0x00,0x00,0x74 ,0x00,0x00,0x00,0x76,0x00,0x00,0x00}; memcpy(login_accepted_packet+16, &account_id, sizeof(int32)); EQ2Packet* app = new EQ2Packet(OP_LoginReplyMsg, login_accepted_packet, sizeof(login_accepted_packet)); QueuePacket(app); } else{ uchar login_accepted_packet[] ={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 ,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x40,0x18,0x00,0x00,0xff,0xde,0x0d ,0x00,0x00,0x01,0x18,0x03,0x05,0x3c,0x02,0x03,0x01,0x00,0xf4,0xf4,0xf4,0xff,0xff ,0xff,0x3d,0x02,0x08,0x01,0x00,0xf4,0xf4,0xf4,0xff,0xff,0xff,0x41,0x02,0x07,0x01 ,0x00,0xf4,0xf4,0xf4,0xff,0xff,0xff,0xae,0x0c,0x00,0x00,0x00,0xff,0xff,0xff,0xff ,0xff,0xff,0x34,0x0f,0x00,0x01,0x01,0x93,0x62,0x44,0xcf,0xcf,0xaf,0x04,0x06,0x3c ,0x02,0x03,0x01,0x00,0xb6,0x36,0x36,0xff,0xff,0xff,0x41,0x02,0x07,0x01,0x00,0xb6 ,0x36,0x36,0xff,0xff,0xff,0x3d,0x02,0x08,0x01,0x00,0xb6,0x36,0x36,0xff,0xff,0xff ,0x0f,0x09,0x00,0x01,0x01,0x67,0x54,0x42,0xa0,0xa0,0x50,0x0f,0x09,0x00,0x01,0x01 ,0x67,0x54,0x42,0xa0,0xa0,0x50,0x34,0x0f,0x00,0x01,0x01,0x93,0x62,0x44,0xcf,0xcf ,0xaf,0x06,0x06,0x31,0x00,0x00,0x01,0x01,0xf4,0xf4,0xf4,0xf4,0xf4,0xf4,0x31,0x00 ,0x00,0x01,0x01,0xf4,0xf4,0xf4,0xf4,0xf4,0xf4,0xf3,0x02,0x03,0x00,0x00,0xff,0xff ,0xff,0xff,0xff,0xff,0x31,0x00,0x07,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0x31 ,0x00,0x08,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xf8,0x0e,0x00,0x01,0x01,0xff ,0xff,0x00,0x80,0x80,0x00,0x07,0x06,0xe6,0x09,0x00,0x01,0x01,0xba,0x7b,0x42,0xba ,0x7b,0x42,0xe6,0x09,0x00,0x01,0x01,0xba,0x7b,0x42,0xba,0x7b,0x42,0xa6,0x01,0x08 ,0x01,0x01,0x77,0x60,0x46,0x77,0x60,0x46,0xaa,0x01,0x07,0x01,0x01,0x77,0x60,0x46 ,0x77,0x60,0x46,0xc7,0x0f,0x03,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xb2,0x0c ,0x00,0x01,0x01,0xff,0xff,0x00,0x80,0x80,0x00,0x09,0x05,0x33,0x02,0x03,0x01,0x00 ,0x2d,0x2d,0x2d,0xff,0xff,0xff,0x34,0x02,0x08,0x01,0x00,0x2d,0x2d,0x2d,0xff,0xff ,0xff,0x38,0x02,0x07,0x01,0x00,0x2d,0x2d,0x2d,0xff,0xff,0xff,0x69,0x09,0x00,0x01 ,0x01,0x6d,0x1c,0x1c,0x93,0x6b,0x6b,0x34,0x0f,0x00,0x01,0x01,0x93,0x62,0x44,0xcf ,0xcf,0xaf,0x0a,0x05,0x69,0x09,0x00,0x01,0x01,0xa7,0xa7,0xeb,0xa7,0xa7,0xeb,0x33 ,0x02,0x03,0x01,0x00,0xf4,0xf4,0xf4,0xff,0xff,0xff,0x38,0x02,0x07,0x01,0x00,0xf4 ,0xf4,0xf4,0xff,0xff,0xff,0x34,0x02,0x08,0x01,0x00,0xf4,0xf4,0xf4,0xff,0xff,0xff ,0x34,0x0f,0x00,0x01,0x01,0x93,0x62,0x44,0xcf,0xcf,0xaf,0x0d,0x04,0xea,0x09,0x00 ,0x01,0x01,0xdd,0xdd,0x8c,0xdd,0xdd,0x8c,0x95,0x02,0x08,0x01,0x00,0xf4,0xf4,0x0a ,0xff,0xff,0xff,0x94,0x02,0x03,0x01,0x00,0xf4,0xf4,0x0a,0xff,0xff,0xff,0x99,0x02 ,0x07,0x01,0x00,0xf4,0xf4,0x0a,0xff,0xff,0xff,0x0e,0x04,0xc6,0x02,0x08,0x01,0x00 ,0x13,0x13,0x13,0xff,0xff,0xff,0xc5,0x02,0x03,0x01,0x00,0x13,0x13,0x13,0xff,0xff ,0xff,0xca,0x02,0x07,0x01,0x00,0x13,0x13,0x13,0xff,0xff,0xff,0x14,0x09,0x00,0x01 ,0x01,0x9c,0x4f,0x4f,0x2b,0x15,0x15,0x10,0x04,0xdf,0x09,0x00,0x01,0x01,0x70,0xba ,0x70,0xba,0x7b,0x42,0x38,0x04,0x08,0x01,0x00,0xb6,0xcd,0x2f,0xff,0xff,0xff,0x37 ,0x04,0x03,0x01,0x00,0xb6,0xcd,0x2f,0xff,0xff,0xff,0x3c,0x04,0x07,0x01,0x00,0xb6 ,0xcd,0x2f,0xff,0xff,0xff,0x11,0x04,0xdf,0x09,0x00,0x01,0x01,0xba,0x7b,0x42,0x62 ,0xb3,0x62,0x38,0x04,0x08,0x01,0x00,0x1a,0x41,0x1a,0xff,0xff,0xff,0x3c,0x04,0x07 ,0x01,0x00,0x1a,0x41,0x1a,0xff,0xff,0xff,0x37,0x04,0x03,0x01,0x00,0x1a,0x41,0x1a ,0xff,0xff,0xff,0x13,0x04,0x59,0x0e,0x00,0x01,0x01,0x3b,0x7c,0x3b,0xe2,0xe2,0x85 ,0xb6,0x03,0x08,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xb5,0x03,0x03,0x00,0x00 ,0xff,0xff,0xff,0xff,0xff,0xff,0xba,0x03,0x07,0x00,0x00,0xff,0xff,0xff,0xff,0xff ,0xff,0x14,0x04,0x59,0x0e,0x00,0x01,0x01,0x2b,0x34,0x21,0xe2,0xe2,0x85,0xa8,0x03 ,0x08,0x01,0x01,0x18,0x18,0x18,0x18,0x18,0x18,0xa7,0x03,0x03,0x01,0x01,0x18,0x18 ,0x18,0x18,0x18,0x18,0xac,0x03,0x07,0x01,0x01,0x18,0x18,0x18,0x18,0x18,0x18,0x17 ,0x04,0x4b,0x0e,0x00,0x01,0x01,0xe6,0x95,0xe6,0xe6,0x95,0xe6,0xda,0x01,0x07,0x01 ,0x01,0x9e,0x9e,0xd8,0xa3,0x6b,0x80,0x92,0x17,0x03,0x01,0x01,0x66,0x42,0x4b,0x9e ,0x9e,0xd8,0xd6,0x01,0x08,0x01,0x01,0x9e,0x9e,0xd8,0xa3,0x6b,0x80,0x18,0x04,0x4d ,0x0e,0x00,0x01,0x01,0xcf,0x2f,0xcf,0xe6,0x95,0xe6,0x92,0x17,0x03,0x01,0x01,0x70 ,0x70,0x70,0x67,0x2b,0x67,0xd6,0x01,0x08,0x01,0x01,0x67,0x2b,0x67,0x50,0x50,0x50 ,0xda,0x01,0x07,0x01,0x01,0x67,0x2b,0x67,0x50,0x50,0x50,0x1a,0x04,0xe4,0x0c,0x00 ,0x01,0x01,0xba,0xff,0xba,0xd4,0xe9,0xff,0x92,0x17,0x03,0x01,0x01,0xda,0xda,0xa5 ,0x60,0x60,0x9e,0xda,0x01,0x07,0x01,0x01,0x60,0x60,0x9e,0xda,0xda,0xa5,0xd6,0x01 ,0x08,0x01,0x01,0x60,0x60,0x9e,0xda,0xda,0xa5,0x1b,0x04,0x92,0x17,0x03,0x01,0x01 ,0x99,0x48,0x48,0xf7,0xcf,0x82,0xda,0x01,0x07,0x01,0x01,0xf7,0xcf,0x82,0x99,0x48 ,0x48,0xd6,0x01,0x08,0x01,0x01,0xf7,0xcf,0x82,0x99,0x48,0x48,0xd7,0x0e,0x00,0x01 ,0x01,0x8e,0x46,0x46,0x2b,0x15,0x15,0x1d,0x04,0xa9,0x08,0x00,0x01,0x01,0xe8,0xb6 ,0x85,0xe8,0xb6,0x85,0x92,0x17,0x03,0x01,0x01,0x57,0x85,0xae,0xd8,0xe8,0xf4,0xd6 ,0x01,0x08,0x01,0x01,0xd8,0xe8,0xf4,0x95,0xb3,0xcd,0xda,0x01,0x07,0x01,0x01,0xd8 ,0xe8,0xf4,0x95,0xb3,0xcd,0x1e,0x04,0x92,0x17,0x03,0x01,0x01,0x62,0x57,0x4d,0xa3 ,0x9e,0x9a,0xd6,0x01,0x08,0x01,0x01,0xff,0xda,0xb6,0x6b,0x57,0x44,0xda,0x01,0x07 ,0x01,0x01,0xff,0xda,0xb6,0x6b,0x57,0x44,0x3a,0x0e,0x00,0x01,0x01,0x2b,0x54,0x54 ,0x2b,0x15,0x15,0x21,0x06,0x64,0x03,0x08,0x01,0x00,0x7e,0x4b,0x46,0xff,0xff,0xff ,0x68,0x03,0x07,0x01,0x00,0x7e,0x4b,0x46,0xff,0xff,0xff,0x63,0x03,0x03,0x01,0x00 ,0x7e,0x4b,0x46,0xff,0xff,0xff,0xa9,0x08,0x00,0x01,0x01,0x1f,0x3f,0x60,0x62,0x62 ,0x62,0xa9,0x08,0x00,0x01,0x01,0x1f,0x3f,0x60,0x62,0x62,0x62,0x42,0x0f,0x00,0x01 ,0x01,0xff,0xff,0x00,0x80,0x80,0x00,0x22,0x06,0xd6,0x0c,0x00,0x01,0x01,0xe6,0x95 ,0xe6,0x1a,0x1a,0x70,0xd6,0x0c,0x00,0x01,0x01,0xe6,0x95,0xe6,0x1a,0x1a,0x70,0x64 ,0x03,0x08,0x01,0x00,0x5d,0x42,0x5d,0xff,0xff,0xff,0x68,0x03,0x07,0x01,0x00,0x5d ,0x42,0x5d,0xff,0xff,0xff,0x63,0x03,0x03,0x01,0x00,0x5d,0x42,0x5d,0xff,0xff,0xff ,0x42,0x0f,0x00,0x01,0x01,0xff,0xff,0x00,0x80,0x80,0x00,0x24,0x06,0x63,0x03,0x03 ,0x01,0x00,0x99,0xc8,0xe2,0xff,0xff,0xff,0x64,0x03,0x08,0x01,0x00,0x99,0xc8,0xe2 ,0xff,0xff,0xff,0x68,0x03,0x07,0x01,0x00,0x99,0xc8,0xe2,0xff,0xff,0xff,0xd6,0x0c ,0x00,0x01,0x01,0x85,0x85,0xa7,0xd1,0xd1,0xac,0xd6,0x0c,0x00,0x01,0x01,0x85,0x85 ,0xa7,0xd1,0xd1,0xac,0x34,0x0f,0x00,0x01,0x01,0x93,0x62,0x44,0xcf,0xcf,0xaf,0x25 ,0x06,0x63,0x03,0x03,0x01,0x00,0xbf,0xa5,0x7e,0xff,0xff,0xff,0x5c,0x03,0x08,0x00 ,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0x60,0x03,0x07,0x00,0x00,0xff,0xff,0xff,0xff ,0xff,0xff,0xb1,0x08,0x00,0x01,0x01,0x90,0x48,0x48,0x90,0x48,0x48,0xb1,0x08,0x00 ,0x01,0x01,0x90,0x48,0x48,0x90,0x48,0x48,0x34,0x0f,0x00,0x01,0x01,0x93,0x62,0x44 ,0xcf,0xcf,0xaf,0x27,0x06,0xb9,0x16,0x08,0x01,0x01,0x3d,0x54,0x3d,0xbc,0xbc,0xbc ,0xb8,0x16,0x03,0x01,0x01,0x3d,0x54,0x3d,0xbc,0xbc,0xbc,0x68,0x03,0x07,0x01,0x00 ,0x3d,0x54,0x3d,0xff,0xff,0xff,0x34,0x0f,0x00,0x01,0x01,0x31,0x4d,0x3f,0xcf,0xcf ,0xaf,0xcd,0x08,0x00,0x01,0x01,0x2b,0x54,0x3f,0x3f,0x98,0x6b,0xcd,0x08,0x00,0x01 ,0x01,0x2b,0x54,0x3f,0x3f,0x98,0x6b,0x28,0x06,0xb9,0x16,0x08,0x01,0x01,0x21,0x21 ,0x31,0x3f,0x3f,0x3f,0xb8,0x16,0x03,0x01,0x01,0x21,0x21,0x31,0x3f,0x3f,0x3f,0x68 ,0x03,0x07,0x01,0x00,0x48,0x48,0x54,0xff,0xff,0xff,0x34,0x0f,0x00,0x01,0x01,0x31 ,0x4d,0x3f,0xcf,0xcf,0xaf,0xa9,0x08,0x00,0x01,0x01,0x1a,0x1a,0x70,0xe6,0x95,0xe6 ,0xa9,0x08,0x00,0x01,0x01,0x1a,0x1a,0x70,0xe6,0x95,0xe6,0x0a,0xd1,0x00,0x00,0x00 ,0xd0,0x00,0x00,0x00,0xcf,0x00,0x00,0x00,0x6e,0x00,0x00,0x00,0x70,0x00,0x00,0x00 ,0x71,0x00,0x00,0x00,0x72,0x00,0x00,0x00,0x73,0x00,0x00,0x00,0x74,0x00,0x00,0x00 ,0x76,0x00,0x00,0x00}; memcpy(login_accepted_packet+16, &account_id, sizeof(int32)); EQ2Packet* app = new EQ2Packet(OP_LoginReplyMsg, login_accepted_packet, sizeof(login_accepted_packet)); QueuePacket(app); } /*EQ2Packet* app = new EQ2Packet(OP_LoginReplyMsg, 0, sizeof(LS_LoginResponse)); LS_LoginResponse* ls_response = (LS_LoginResponse*)app->pBuffer; ls_response->accountid = GetAccountID(); QueuePacket(app);*/ } void Client::SendWorldList(){ EQ2Packet* pack = world_list.MakeServerListPacket(lsadmin, version); EQ2Packet* dupe = pack->Copy(); DumpPacket(dupe->pBuffer,dupe->size); QueuePacket(dupe); return; } void Client::QueuePacket(EQ2Packet* app){ eqnc->EQ2QueuePacket(app); } void Client::WorldResponse(int32 worldid, int8 response, char* ip_address, int32 port, int32 access_key) { LWorld* world = world_list.FindByID(worldid); if(world == 0) { FatalError(0); return; } if(response != 1){ if(response == PLAY_ERROR_CHAR_NOT_LOADED){ string pending_play_char_name = database.GetCharacterName(pending_play_char_id, worldid); if(database.VerifyDelete(GetAccountID(), pending_play_char_id, pending_play_char_name.c_str())){ GetLoginAccount()->removeCharacter((char*)pending_play_char_name.c_str()); } } FatalError(response); return; } PacketStruct* response_packet = configReader.getStruct("LS_PlayResponse", GetVersion()); if(response_packet){ safe_delete(playWaitTimer); response_packet->setDataByName("response", 1); response_packet->setSmallStringByName("server", ip_address); response_packet->setDataByName("port", port); response_packet->setDataByName("account_id", GetAccountID()); response_packet->setDataByName("access_code", access_key); EQ2Packet* outapp = response_packet->serialize(); QueuePacket(outapp); safe_delete(response_packet); disconnectTimer = new Timer(1000); disconnectTimer->Start(); } return; } void Client::FatalError(int8 response) { safe_delete(playWaitTimer); SendPlayFailed(response); } void Client::SendPlayFailed(int8 response){ PacketStruct* response_packet = configReader.getStruct("LS_PlayResponse", GetVersion()); if(response_packet){ response_packet->setDataByName("response", response); response_packet->setSmallStringByName("server", ""); response_packet->setDataByName("port", 0); response_packet->setDataByName("account_id", GetAccountID()); response_packet->setDataByName("access_code", 0); EQ2Packet* outapp = response_packet->serialize(); QueuePacket(outapp); safe_delete(response_packet); } } void ClientList::Add(Client* client) { MClientList.writelock(); client_list[client] = true; MClientList.releasewritelock(); } Client* ClientList::Get(int32 ip, int16 port) { Client* ret = 0; map::iterator itr; MClientList.readlock(); for(itr = client_list.begin(); itr != client_list.end(); itr++){ if(itr->first->GetIP() == ip && itr->first->GetPort() == port){ ret = itr->first; break; } } MClientList.releasereadlock(); return ret; } void ClientList::FindByCreateRequest(){ Client* client = 0; map::iterator itr; MClientList.readlock(); for(itr = client_list.begin(); itr != client_list.end(); itr++){ if(itr->first->AwaitingCharCreationRequest()){ if(!client) client = itr->first; else{ client = 0;//more than 1 character waiting, dont want to send rejection to wrong one break; } } } MClientList.releasereadlock(); if(client) client->CharacterRejected(UNKNOWNERROR_REPLY); } Client* ClientList::FindByLSID(int32 lsaccountid) { Client* client = 0; map::iterator itr; MClientList.readlock(); for(itr = client_list.begin(); itr != client_list.end(); itr++){ if(itr->first->GetAccountID() == lsaccountid){ client = itr->first; break; } } MClientList.releasereadlock(); return client; } void ClientList::SendPacketToAllClients(EQ2Packet* app){ Client* client = 0; map::iterator itr; MClientList.readlock(); if(client_list.size() > 0){ for(itr = client_list.begin(); itr != client_list.end(); itr++){ itr->first->QueuePacket(app->Copy()); } } safe_delete(app); MClientList.releasereadlock(); } void ClientList::Process() { Client* client = 0; vector erase_list; map::iterator itr; MClientList.readlock(); for(itr = client_list.begin(); itr != client_list.end(); itr++){ client = itr->first; if(!client->Process()) erase_list.push_back(client); } MClientList.releasereadlock(); if(erase_list.size() > 0){ vector::iterator erase_itr; MClientList.writelock(); for(erase_itr = erase_list.begin(); erase_itr != erase_list.end(); erase_itr++){ client = *erase_itr; struct in_addr in; in.s_addr = client->getConnection()->GetRemoteIP(); net.numclients--; cout << Timer::GetCurrentTime2() << " Removing client from ip: " << inet_ntoa(in) << " port: " << ntohs(client->getConnection()->GetRemotePort()) << " Name: " << client->GetAccountName() << endl; client->getConnection()->SetState(CLOSED); net.UpdateWindowTitle(); client_list.erase(client); } MClientList.releasewritelock(); } }