Files
2022-10-26 12:25:11 +08:00

250 lines
9.1 KiB
C++

#include "stdafx.h"
#include "./CharInfo.h"
#include <time.h>
#include <SCStream.h>
#include <LogTimeFormat.h>
#include <WZ_MD5.h>
#include "User.h"
#include "TempUser.h"
#include "UserManager.h"
#include <AgentServer.h>
//
#include <PacketHandler/PacketHandler.h>
//==================================================================================================
ns_object::CharacterList::PoolInstance*
ns_object::CharacterList::pool_instance_s = NULL;
struct ns_object::CharacterList::PoolInstance
{
PoolInstance()
{
pool_instance.Initialize(20, 20, "CharacterInfoList", NULL);
ZeroMemory(&empty_info, sizeof(empty_info));
}
~PoolInstance()
{
pool_instance.Release();
}
//
util::CMemoryPoolFactory<CharacterInfoList> pool_instance;
CharacterInfoList empty_info;
};
//==================================================================================================
ns_object::CharacterList::CharacterList()
{
static ns_object::CharacterList::PoolInstance pool_instance;
pool_instance_s = &pool_instance;
//
ZeroMemory(this, sizeof(*this));
};
ns_object::CharacterList::~CharacterList()
{
if (character_infos)
{
pool_instance_s->pool_instance.Free(character_infos);
character_infos = NULL;
};
}
void ns_object::CharacterList::Init() // called by User::Init
{
ASSERT(character_infos == NULL);
ZeroMemory(this, sizeof(*this));
character_infos = reinterpret_cast<CharacterInfoList*>(pool_instance_s->pool_instance.Alloc());
ZeroMemory(character_infos, sizeof(*character_infos));
}
void ns_object::CharacterList::Release() // called by User::Release
{
if (FlowControl::FCAssert(character_infos != NULL))
{
pool_instance_s->pool_instance.Free(character_infos);
character_infos = NULL;
};
}
bool ns_object::CharacterList::SelectCharacter(int selecting_char_slot_index)
{
BOOST_STATIC_ASSERT(_countof(character_infos->nodes) == MAX_CHARACTER_LIST_NUM);
bool in_ranges = (selecting_char_slot_index >= 0 &&
selecting_char_slot_index < MAX_CHARACTER_LIST_NUM);
bool validated_char = in_ranges && occupied_slots[selecting_char_slot_index] &&
(character_infos->nodes[selecting_char_slot_index].m_CharGuid != 0);
if (in_ranges == false)
{
CharacterInfoList* backup = character_infos;
ZeroMemory(this, sizeof(*this));
this->selected_char_slot_index = MAX_CHARACTER_LIST_NUM;
character_infos = backup;
ZeroMemory(character_infos, sizeof(*character_infos));
return true;
};
//
this->selected_char = NULL;
this->selected_char_slot_index = MAX_CHARACTER_LIST_NUM;
ZeroMemory(character_infos, static_cast<size_t>(
reinterpret_cast<char*>(character_infos->char_name_hashes) -
reinterpret_cast<char*>(character_infos)));
//
if (validated_char == false) {
return false;
}
//
this->selected_char = &character_infos->nodes[selecting_char_slot_index];
this->selected_char_slot_index = selecting_char_slot_index;
return true;
}
//==================================================================================================
void ns_object::CharacterList::SerializeCharacterPart(BYTE slot_index,
SERVER_CHARACTER_PART& INOUT parts, eSERIALIZE se)
{
if (FlowControl::FCAssert(slot_index < MAX_CHARACTER_SLOT_NUM) == false) {
return;
};
if (se == SERIALIZE_LOAD)
{
assert(!"currently, default game flow can't enter at this point");
parts = character_infos->nodes[slot_index];
return;
};
ASSERT(se == SERIALIZE_STORE);
// CHANGES: f110517.3L, the calling case of 'SetOccupiedSlot' changes to post this serialization
ASSERT(this->occupied_slots[slot_index] == false);
SERVER_CHARACTER_PART* const dest_part = &character_infos->nodes[slot_index];
*dest_part = parts;
if (dest_part->m_DelChk != 0)
{
dest_part->m_tszDelDate[_countof(dest_part->m_tszDelDate) - 1] = _T('\0');
};
}
void ns_object::CharacterList::LoadClientCharacterPart(BYTE slot_index,
CLIENT_CHARACTER_PART* const result_parts) const
{
if (FlowControl::FCAssert(slot_index < MAX_CHARACTER_SLOT_NUM) == false) {
return;
};
const SERVER_CHARACTER_PART& source_part = character_infos->nodes[slot_index];
result_parts->m_bySlot = source_part.m_bySlot;
//source_part.m_tszCharName[MAX_CHARNAME_LENGTH] = '\0';
BOOST_STATIC_ASSERT(
sizeof(result_parts->m_tszCharName) == sizeof(source_part.m_tszCharName) &&
_countof(result_parts->m_tszCharName) == _countof(source_part.m_tszCharName));
int len = _sntprintf(result_parts->m_tszCharName, _countof(result_parts->m_tszCharName),
"%s", source_part.m_tszCharName);
// ^ : prevent security problem
assert(len > 0);
result_parts->m_tszCharName[_countof(result_parts->m_tszCharName) - 1] = _T('\0');
result_parts->m_byHeight = source_part.m_byHeight;
result_parts->m_byFace = source_part.m_byFace;
result_parts->m_byHair = source_part.m_byHair;
result_parts->m_byClass = source_part.m_byClass;
result_parts->m_LV = source_part.m_LV;
result_parts->m_iRegion = source_part.m_iRegion;
result_parts->m_sX = source_part.m_sX;
result_parts->m_sY = source_part.m_sY;
result_parts->m_sZ = source_part.m_sZ;
result_parts->m_ChangeOfClassStep = source_part.m_ChangeOfClassStep;
result_parts->m_PetSlotStream = source_part.m_PetSlotStream;
result_parts->m_bSummoned = source_part.m_bSummoned;
ASSERT(source_part.m_EquipItemInfo.m_Count <= MAX_EQUIPMENT_SLOT_NUM);
;{
BOOST_STATIC_ASSERT(_countof(result_parts->m_EquipItemInfo.m_Slot) ==
_countof(source_part.m_EquipItemInfo.m_Slot));
int number_of_items = source_part.m_EquipItemInfo.m_Count;
; number_of_items = min(number_of_items, MAX_EQUIPMENT_SLOT_NUM);
EQUIP_ITEM_INFO::SLOT_TYPE* dest_it = result_parts->m_EquipItemInfo.m_Slot;
const _EQUIP_TOTAL_INFO::SLOT_TYPE* src_it = source_part.m_EquipItemInfo.m_Slot;
const _EQUIP_TOTAL_INFO::SLOT_TYPE* src_end = \
&source_part.m_EquipItemInfo.m_Slot[number_of_items];
for (; src_it != src_end; ++src_it, ++dest_it)
{
dest_it->m_Pos = src_it->m_Pos;
// RENDER_ITEMSTREAMEX <- ITEMSTREAMEX
CopyStream(dest_it->m_Stream, src_it->m_Stream);
};
result_parts->m_EquipItemInfo.m_Count = static_cast<POSTYPE>(number_of_items);
//
};
result_parts->m_DelChk = source_part.m_DelChk;
if (result_parts->m_DelChk != 0)
{
// make to pre-check and prevention
//source_part.m_tszDelDate[MAX_SMALLDATETIME_SIZE] ='\0';
strncpy(result_parts->m_tszDelDate, source_part.m_tszDelDate,
_countof(result_parts->m_tszDelDate));
result_parts->m_tszDelDate[_countof(result_parts->m_tszDelDate) - 1] = '\0';
}
#ifdef _NA_002050_20110216_ADD_GENDER
result_parts->gender = source_part.gender;
#endif
//_NA_004035_20120227_COSTUME_ITEM
result_parts->is_equipped_costume = source_part.is_equipped_costume;
result_parts->costume_item_pos = source_part.costume_item_pos;
result_parts->costume_item_code = source_part.costume_item_code;
#ifdef _NA_008610_20160104_ADD_DECORATECOSTUME
result_parts->is_equipped_decorate_costume = source_part.is_equipped_deco_costume;
result_parts->decorate_costume_item_pos = source_part.deco_costume_item_pos;
result_parts->decorate_costume_item_code = source_part.deco_costume_item_code;
#endif //_NA_008610_20160104_ADD_DECORATECOSTUME
}
//==================================================================================================
void User::SetCharName(BYTE slot_index, const TCHAR* char_name)
{
if (FlowControl::FCAssert(slot_index < MAX_CHARACTER_LIST_NUM) == false) {
return;
};
SERVER_CHARACTER_PART* const char_part = &character_list_.character_infos->nodes[slot_index];
_tcsncpy(char_part->m_tszCharName, char_name, _countof(char_part->m_tszCharName));
char_part->m_tszCharName[_countof(char_part->m_tszCharName) - 1] = _T('\0');
}
// 유효한 슬롯인지 여부 처리
void User::SetOccupiedSlot(BYTE slot_index, bool val)
{
if (bool out_range = (slot_index >= MAX_CHARACTER_LIST_NUM)) {
return;
};
character_list_.occupied_slots[slot_index] = val;
if (val)
{
// CHANGES: f110517.3L, added to configure hash value for the character name.
const SERVER_CHARACTER_PART& src_part = character_list_.character_infos->nodes[slot_index];
TCHAR lower_char_name[_countof(src_part.m_tszCharName)];
_tcsncpy(lower_char_name, src_part.m_tszCharName, _countof(lower_char_name));
lower_char_name[_countof(lower_char_name) - 1] = _T('\0');
_tcslwr(lower_char_name);
//
util::HashKey hash_value = util::StreamHashKey::GetStringHashKey(lower_char_name);
character_list_.character_infos->char_name_hashes[slot_index] = hash_value;
}
else
{
character_list_.character_infos->char_name_hashes[slot_index] = 0;
}
}