160 lines
5.0 KiB
C++
160 lines
5.0 KiB
C++
// Copyright (C) 2007 EQ2EMulator Development Team (http://www.eq2emulator.net) - GPLv3
|
|
|
|
#pragma once
|
|
|
|
#include <vector>
|
|
#include <string>
|
|
|
|
#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<char*>(data), size);
|
|
}
|
|
|
|
// Loads character data from database and populates character list for specified account
|
|
void loadData(int32 account, vector<CharSelectProfile*> 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
|
|
}; |