// Copyright (C) 2007 EQ2EMulator Development Team (http://www.eq2emulator.net) - GPLv3 #pragma once #include #include #include "lworld.hpp" #include "login_structs.hpp" #include "login_database.hpp" #include "../common/types.hpp" #include "../common/data_buffer.hpp" #include "../common/config_reader.hpp" #include "../common/misc_functions.hpp" #include "../common/global_headers.hpp" #include "../common/eq_common_structs.hpp" #include "../common/packet/eq_packet.hpp" extern ConfigReader configReader; extern LWorldList world_list; extern LoginDatabase database; using std::vector; using std::string; // Character profile data for character selection screen class CharSelectProfile : public DataBuffer { public: // Constructor - initializes character profile with version-specific packet structure CharSelectProfile(int16 version) { deleted = false; packet = configReader.getStruct("CharSelectProfile", version); // Initialize all 24 equipment slots to default values for (int8 i = 0; i < 24; i++) { packet->setEquipmentByName("equip", 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, i); } } // Destructor - safely cleans up packet structure ~CharSelectProfile() { safe_delete(packet); } // Serializes character profile data for transmission void SaveData(int16 in_version) { Clear(); AddData(*packet->serializeString()); } PacketStruct* packet; // Packet structure containing character data int16 size; // Size of serialized data bool deleted; // Flag indicating if character is marked for deletion }; // Character selection list containing multiple character profiles class LS_CharSelectList : public DataBuffer { public: // Serializes character list data with account information for specified client version EQ2Packet* serialize(int16 version) { Clear(); AddData(num_characters); AddData(char_data); if (version <= 561) { // Early client version uses simplified account info structure LS_CharListAccountInfoEarlyClient account_info; account_info.account_id = account_id; account_info.unknown1 = 0xFFFFFFFF; account_info.unknown2 = 0; account_info.maxchars = 7; // Live has a max of 7 on gold accounts base account_info.unknown4 = 0; AddData(account_info); } else { // Later client versions use extended account info structure LS_CharListAccountInfo account_info; account_info.account_id = account_id; account_info.unknown1 = 0xFFFFFFFF; account_info.unknown2 = 0; account_info.maxchars = database.GetMaxCharsSetting(); account_info.vet_adv_bonus = database.GetAccountBonus(account_id); account_info.vet_trade_bonus = 0; account_info.unknown4 = 0; for (int i = 0; i < 3; i++) account_info.unknown5[i] = 0xFFFFFFFF; account_info.unknown5[3] = 0; AddData(account_info); } return new EQ2Packet(OP_AllCharactersDescReplyMsg, getData(), getDataSize()); } // Appends character data to the character list void addChar(uchar* data, int16 size) { char_data.append(reinterpret_cast(data), size); } // Loads character data from database and populates character list for specified account void loadData(int32 account, vector charlist, int16 version) { account_id = account; num_characters = 0; char_data = ""; CharSelectProfile* character = nullptr; for (auto itr = charlist.begin(); itr != charlist.end(); itr++) { character = *itr; int32 serverID = character->packet->getType_int32_ByName("server_id"); if (character->deleted) { // Workaround for old clients <= 561 that crash if you delete a char // Doesn't refresh the char panel correctly character->packet->setDataByName("name", "(deleted)"); character->packet->setDataByName("charid", 0xFFFFFFFF); character->packet->setDataByName("name", 0xFFFFFFFF); character->packet->setDataByName("server_id", 0xFFFFFFFF); character->packet->setDataByName("created_date", 0xFFFFFFFF); character->packet->setDataByName("unknown1", 0xFFFFFFFF); character->packet->setDataByName("unknown2", 0xFFFFFFFF); character->packet->setDataByName("flags", 0xFF); } else if (serverID == 0 || !world_list.FindByID(serverID)) { continue; } num_characters++; character->SaveData(version); addChar(character->getData(), character->getDataSize()); } } int8 num_characters; // Number of characters in the list int32 account_id; // Account ID for this character list string char_data; // Serialized character data buffer }; // Request packet for character deletion operations class LS_DeleteCharacterRequest : public DataBuffer { public: // Loads character deletion request data from incoming packet void loadData(EQApplicationPacket* packet) { InitializeLoadData(packet->pBuffer, packet->size); LoadData(character_number); LoadData(server_id); LoadData(spacer); LoadDataString(name); } int32 character_number; // Character slot number to delete int32 server_id; // Server ID where character exists int32 spacer; // Padding/alignment bytes EQ2_16BitString name; // Character name to delete };