#include "stdafx.h" #include "./CSunOnlineItem.h" #ifdef __NA000000_090906_SOLAR_SLOT_UPDATE_VER6__ #include #include #include #include "./util/util.h" #include "./logic/logic.h" //================================================================================================== struct XmlElemStack { XmlElemStack(BOOLEAN is_decode, CMarkupArchive& xml, const char* name) : xml_(xml) { if(is_decode) xml_.AddChildElem(name); xml_.IntoElem(); } ~XmlElemStack() { xml_.OutOfElem(); } CMarkupArchive& xml_; }; //================================================================================================== CSunOnlineItem::CSunOnlineItem(CCSunOnline* root) : root_(root) { } void CSunOnlineItem::_Serialize_EtherWeapon(BOOLEAN is_decode, CMarkupArchive& xml, const nsSlot::ItemRuleInfo& item_rule_info, SCItemSlot& item_slot) { BOOLEAN is_ether_weapon = false; BYTE ether_bullet_index = 0; if(is_decode) { if(item_rule_info.is_weapon && (is_ether_weapon = item_slot.IsEquipEtherDevice())) ether_bullet_index = item_slot.GetEtherBulletIndex(); xml.AddChildElemEx("IsEquipEtherDevice", is_ether_weapon); xml.AddChildElemEx("EtherBulletIndex", ether_bullet_index); } else { xml.FindGetChildData("IsEquipEtherDevice", is_ether_weapon); if(is_ether_weapon != 0) { item_slot.SetEtherBulletIndex(true); xml.FindGetChildData("EtherBulletIndex", ether_bullet_index);//¹«±â¿¡ źȯ ÀåÂø item_slot.SetEtherBulletIndex(ether_bullet_index); } } } void CSunOnlineItem::_Serialize_PetItem(BOOLEAN is_decode, CMarkupArchive& xml, const nsSlot::ItemRuleInfo& item_rule_info, SCItemSlot& item_slot) { BOOLEAN is_pet = false; BYTE fullness = 0; BYTE intimacy = 0; BOOLEAN exist_name = false; BOOLEAN is_summoned = false; char pet_name[MAX_PET_NAME_LENGTH + 1]; if(is_decode) { if(item_rule_info.is_pet) is_pet = true; xml.AddChildElemEx("IsPetItem", is_pet); const SCPetInfo* pet_info = 0; if(is_pet && (pet_info = item_slot.GetPetInfo())) { fullness = pet_info->GetFullness(); intimacy = pet_info->GetIntimacy(); exist_name = !!pet_info->IsSetPetName(); xml.AddChildElemEx("Fullness", fullness); xml.AddChildElemEx("Initimacy", intimacy); xml.AddChildElemEx("IsPetName", exist_name); const char* src_name = pet_info->GetPetName(); StringCchCopy(pet_name, _countof(pet_name), src_name); pet_name[_countof(pet_name) - 1] = '\0'; xml.AddChildElemEx("PetName", pet_name); is_summoned = !!item_slot.IsPetLocked(); xml.AddChildElemEx("IsPetLocked", is_summoned); } else { _LOG(__FUNCTION__"|PetInfo=NULL|"); } } else { xml.FindGetChildData("IsPetItem", is_pet); if(is_pet != 0 && item_rule_info.is_pet == 0) { _LOG(__FUNCTION__"|Msg=Invalid Pet|ItemCode=%d|", item_slot.GetCode()); } else if(is_pet != 0) { SCPetInfo* pet_info = item_slot.GetPetInfo(); //assert(pet_info != 0) xml.FindGetChildData("Fullness", fullness);//Æ÷¸¸°¨ pet_info->SetFullness(fullness); xml.FindGetChildData("Initimacy", intimacy);//Ä£¹Ðµµ pet_info->SetIntimacy(intimacy); xml.FindGetChildData("IsPetName", exist_name);// if(exist_name != 0) { std::string strName; xml.FindGetChildData("PetName", strName);// pet_info->SetPetName(const_cast(strName.c_str())); } } } } void CSunOnlineItem::_Serialize_FateItem(BOOLEAN is_decode, CMarkupArchive& xml, const nsSlot::ItemRuleInfo& item_rule_info, SCItemSlot& item_slot, char time_string_inout[32]) { DWORD64 date_time = 0; WORD atk_def_ratio = 0; BOOLEAN is_identify = false; DURATYPE max_duration = 0; WORD period = 0; char buffer[256]; if(item_rule_info.is_fate == 0) { _LOG(__FUNCTION__"|Unexpected logic|"); __asm { int 3 }; } if(is_decode) { date_time = item_slot.GetDateTime(); _snprintf(time_string_inout, 32, "%I64d", date_time); atk_def_ratio = item_slot.GetFateAtkDefRatio(); is_identify = item_slot.GetFateIdentify(); max_duration = item_slot.GetFateDuraMax(); period = item_slot.GetFatePeriod(); //item_slot.IsFateItem() _snprintf(buffer, _countof(buffer), "[%u:%d:%d:%u]", atk_def_ratio, is_identify, max_duration, period); xml.AddChildElem("Lucky", buffer); } else { date_time = static_cast(_atoi64(time_string_inout)); SYSTEMTIME systime; util::YYYYMMDDHHMMSSToSYSTEMTIME(date_time, systime); _snprintf(buffer, _countof(buffer), "%04d%02d%02d%02d%02d%02d", systime.wYear, systime.wMonth, systime.wDay, systime.wHour, systime.wMinute, systime.wSecond); // ½Ã°£À» ¼ÂÆÃ(ÃÊ ´ÜÀ§) BOOST_STATIC_ASSERT(_countof(buffer) >= 32); if(strncmp(buffer, time_string_inout, 32) == 0) { #ifdef _FIXED_DATETIIME_METHOD_ item_slot.SetFixedDateTime(date_time); #endif } else { item_slot.SetDateTime(date_time); } std::string stl_fate_string; if(xml.FindGetChildData("Lucky", stl_fate_string) == 0) { _LOG(__FUNCTION__"|Unexpected logic|"); __asm { int 3 }; } std::string::size_type length = stl_fate_string.length(); if(length == 0 || _countof(buffer) <= length) return; strncpy(buffer, stl_fate_string.c_str(), _countof(buffer)); buffer[_countof(buffer) - 1] = '\0'; const char* token = strtok(buffer, "[ ]"); int count = 0; while(token != 0) { ++count; strncpy(buffer, token, _countof(buffer)); token = strtok(NULL, "[ ]"); } if(count != 1) { _LOG(__FUNCTION__"|Msg=invalid format lucky option|"); __asm { int 3 }; } count = 0; token = strtok(buffer, ":"); atk_def_ratio = (WORD)atoi(token); ++count; token = strtok(NULL, ":"); is_identify = !!atoi(token); ++count; token = strtok(NULL, ":"); max_duration = (DURATYPE)atoi(token); ++count; token = strtok(NULL, ":"); period = (WORD)atoi(token); ++count; item_slot.SetFateAtkDefRatio(atk_def_ratio); item_slot.SetFateIdentify(is_identify); item_slot.SetFateDuraMax(max_duration); item_slot.SetFatePeriod(period); } } void CSunOnlineItem::_Serialize_LimitedItem(BOOLEAN is_decode, CMarkupArchive& xml, const nsSlot::ItemRuleInfo& item_rule_info, SCItemSlot& item_slot) { WORD limited_index = 0; int damage_ratio = 0; int limit_value_ratio = 0; DURATYPE max_duration = 0; DURATYPE max_duration_for_restore = 0; BYTE number_of_repairs = 0; char buffer[256]; if(is_decode) { if(item_rule_info.is_limited == 0 || item_slot.IsLimited() == 0) { _LOG(__FUNCTION__"|Unexpected logic|"); __asm { int 3 }; } limited_index = item_slot.GetLimitedIndex(); damage_ratio = item_slot.GetDamageRatio(); limit_value_ratio = item_slot.GetLimitValueRatio(); max_duration = item_slot.GetLimitedDuraMax(); max_duration_for_restore = item_slot.GetLimitedDuraMMax(); number_of_repairs = item_slot.GetLimitedRepairCount(); _snprintf(buffer, _countof(buffer), "[%u:%d:%d:%d:%d:%d]", limited_index, damage_ratio, limit_value_ratio, max_duration, max_duration_for_restore, number_of_repairs); xml.AddChildElem("Limited", buffer); } else { std::string stl_limited; if(xml.FindGetChildData("Limited", stl_limited) == 0) return; std::string::size_type length = stl_limited.length(); if(length == 0 || _countof(buffer) <= length) return; strncpy(buffer, stl_limited.c_str(), _countof(buffer)); buffer[_countof(buffer) - 1] = '\0'; const char* token = strtok(buffer, "[ ]"); int count = 0; while(token != 0) { ++count; strncpy(buffer, token, _countof(buffer)); token = strtok(NULL, "[ ]"); } if(count != 1) { _LOG(__FUNCTION__"|Msg=invalid format limited option|"); __asm { int 3 }; } count = 0; token = strtok(buffer, ":"); limited_index = (WORD)atoi(token); ++count; token = strtok(NULL, ":"); damage_ratio = atoi(token); ++count; token = strtok(NULL, ":"); limit_value_ratio = atoi(token); ++count; token = strtok(NULL, ":"); max_duration = (DURATYPE)atoi(token); ++count; token = strtok(NULL, ":"); max_duration_for_restore = (DURATYPE)atoi(token); ++count; token = strtok(NULL, ":"); number_of_repairs = (BYTE)atoi(token); ++count; item_slot.SetLimitedIndex(limited_index); item_slot.SetDamageRatio(damage_ratio); item_slot.SetLimitValueRatio(limit_value_ratio); item_slot.SetLimitedDuraMax(max_duration); item_slot.SetLimitedDuraMMax(max_duration_for_restore); item_slot.SetLimitedRepairCount(number_of_repairs); } } //================================================================================================== BOOLEAN CSunOnlineItem::DecodeItem(CMarkupArchive& xml, const SCItemSlot& item_slot, POSTYPE item_pos) { XmlElemStack stack_item(true, xml, "ITEM"); const nsSlot::ItemRuleInfo& item_rule_info = item_slot.GetItemRuleInfo(); if(item_rule_info.is_valid_item == 0) return false; //------------------------------- // default environment static std::string stl_temp; // const BASE_ITEMINFO* item_info = item_slot.GetItemInfo(); const SLOTCODE item_code = item_slot.GetCode(); xml.AddChildElemEx("Code", item_code); //ÄÚµå¹øÈ£ xml.AddChildElemEx("Pos", item_pos); //Àκ¥»ó À§Ä¡. { // item name setup... const char* item_name = STRTBL_PARSER1->GetStringByCode(item_info->m_NCode); stl_temp.resize(0); if(item_name != 0) stl_temp = item_name; if(item_info->m_SCNCode != 0) { //2nd ³×ÀÓÄÚµå item_name = STRTBL_PARSER1->GetStringByCode(item_info->m_SCNCode); if(item_name != 0) stl_temp += item_name; } item_name = stl_temp.c_str(); xml.AddChildElem("Name", item_name); //¾ÆÀÌÅÛ¸í }; // lock infos... xml.AddChildElemEx("Block", item_slot.IsBlocked()); //¾ÆÀÌÅÛ Block¿©ºÎ //BUILD_KOREA_061211-- { xml.AddChildElemEx("Type", item_info->m_wType); //ŸÀÔ xml.AddChildElemEx("SubType", item_info->m_wSubType); //¼­ºêŸÀÔ xml.AddChildElemEx("ChargeType", item_info->m_ChargeType); //À¯·áȭŸÀÔ xml.AddChildElemEx("ChargeSubType", item_info->m_ChargeSubType); //À¯·áÈ­¼­ºêŸÀÔ }; { xml.AddChildElemEx("DBType", item_slot.GetType()); //¼­¹ö±ºÅ¸ÀÔ xml.AddChildElemEx("Serial", item_slot.GetSerial()); //½Ã¸®¾ó xml.AddChildElemEx("WorldSerial", item_slot.GetWorldSerial()); //¿ùµå ½Ã¸®¾ó if(item_slot.CanEquip()) xml.AddChildElemEx("EqPos", item_info->m_wEqPos); //ÀåºñÀ§Ä¡ else xml.AddChildElemEx("EqPos", -1); //ÀåºñÀ§Ä¡ // item_slot.WithDura() : ³»±¸µµ¸¦ °¡Áö´Â ¾ÆÀÌÅÛÀΰ¡? true=Yes if(item_slot.WithDura() != 0) { xml.AddChildElemEx("IsDura", 1); xml.AddChildElemEx("Dura", item_slot.GetDura()); } else { xml.AddChildElemEx("IsDura", 0); xml.AddChildElemEx("Dura", item_slot.GetNum()); } }; #ifdef __NA_1247_POSSESSION_ITEM if(item_slot.IsPossessionItem()) { xml.AddChildElemEx("IsPossessionType", 1); xml.AddChildElemEx("IsPossession", item_slot.GetIdentifyPossession()); } else { xml.AddChildElemEx(_T("IsPossessionType"), 0); } #ifdef __NA_0_POSSESSION_ITEM_DROP xml.AddChildElemEx("IsDestroyItem", item_slot.IsDestroyItem() ? 1 : 0); //µð¹ÙÀο©ºÎ #endif #endif // (NOTE) element°¡ Á¸ÀçÇØ¾ß ÇÏ´Â ºÎºÐÀÌ ÀÖ´ÂÁö¶ó filteringÀ» ¼öÇàÇÏÁö ¾Ê´Â´Ù. _Serialize_EtherWeapon(true, xml, item_rule_info, const_cast(item_slot)); _Serialize_PetItem(true, xml, item_rule_info, const_cast(item_slot)); { // process time facilities BOOLEAN is_progress = item_slot.IsProgressTime(); BOOLEAN is_expired = item_slot.IsExpiredTime(); BOOLEAN is_wait_time = item_slot.IsExpiredWaitTime(); xml.AddChildElemEx("ChargeOnUse", is_progress); // ÀåÂø½Ã ŸÀÌ¸Ó µ¿ÀÛ ¾ÆÀÌÅÛÀÏ °æ¿ì ±× ¿©ºÎ xml.AddChildElemEx("IsExpiredTime", is_expired); // ¸¸·á ¿©ºÎ //#ifdef __NA_000493_20070712_SHOP_WEAPON_ARMOR_ITEM xml.AddChildElemEx("IsExpiredWaitTime", is_wait_time); //¸¸·á ÀÌÈÄ ´ë±â »óÅ ¿©ºÎ }; BOOLEAN with_timer = item_rule_info.IsEnableTimer(); char time_buffer[32] = { 0, }; // need re-arrangement // (OLD) 11 == item_info->m_wSubType if(item_rule_info.is_fate) { _Serialize_FateItem(true, xml, item_rule_info, const_cast(item_slot), time_buffer); } else { //GetItemChargeExpireTime(item_info->m_ChargeSubType, item_slot, xml, pszTime); BOOST_STATIC_WARNING(0); } xml.AddChildElem("ChargeExpireTime", time_buffer); // »ç¿ë¸¸·á ½Ã°£ //--BUILD_KOREA_061211 { //divine setup // same field 'divine' and 'set' xml.AddChildElemEx("IsDivine", item_slot.IsDivine()); //µð¹ÙÀο©ºÎ xml.AddChildElemEx("SET", item_slot.GetSet()); //set }; { //enchant option xml.AddChildElemEx("Enchant", item_slot.GetEnchant()); //ÀÎþƮ¿É¼ÇÁ¤º¸ }; { // rank options stl_temp.resize(0); stl_temp = root_->ConvertRankType(item_slot.GetRank()); xml.AddChildElem("RankType", stl_temp.c_str()); //ÇöÀç ·©Å© }; // extra options int extra_option_index = item_slot.GetNOptionValueIndex(); xml.AddChildElemEx("NOptionValue", extra_option_index); if(extra_option_index != 0) { ExtraStoneOptionInfoParser* pExtraStoneParser = ExtraStoneOptionInfoParser::Instance(); const sEXTRASTONE_OPT_INFO* pInfo = pExtraStoneParser->GetExtraStoneOptionInfo(item_info->m_wType /*, item_slot.GetItemInfo()->m_LV*/); if(pInfo) xml.AddChildElemEx("NOptionNCode", pInfo->m_dwOptionNCode); } { // rank options... int attr_index = 0; BYTE attr_value = 0; eATTR_TYPE attr_type = eATTR_TYPE_INVALID; int number_of_options = 0; int upperbound = 0; char temp_buffer[256]; int buffer_offset = 0; char buffer[1024]; buffer[0] = '\0'; if(item_rule_info.IsEnableRank() == 0) { xml.AddChildElem("RANK", buffer); } else { buffer_offset += _snprintf(&buffer[buffer_offset], _countof(buffer) - buffer_offset, "[ "); upperbound = item_slot.GetRank() + 1; for(int rank_inc = RANK_D; rank_inc < upperbound; ++rank_inc) { eRANK rank = (eRANK)rank_inc; attr_value = item_slot.GetRankAttrValue(rank); const sRANK_OPTION* option = item_slot.GetRankAttrDesc(rank); if(option == 0) continue; if(option->m_OptionNCode == 0) continue; attr_index = option->m_iOptionIndex; GetStringByCode(option->m_OptionNCode, temp_buffer, _countof(temp_buffer)); const char* rank_string = root_->ConvertRankType(rank).c_str(); //·©Å©¸í, ÅØ½ºÆ®, ¹ë·ù, À妽º ¼øÀ¸·Î ³Ñ°ÜÁØ´Ù. buffer_offset += _snprintf(&buffer[buffer_offset], _countof(buffer) - buffer_offset, "%s:%s:%d:%d ", rank_string, temp_buffer, attr_value, attr_index); ++number_of_options; } buffer_offset += _snprintf(&buffer[buffer_offset], _countof(buffer) - buffer_offset, "]"); if(number_of_options != 0) buffer[0] = '\0'; xml.AddChildElem("RANK", buffer); //À§¿¡¼­ ¸¸µç ½ºÆ®¸µ°ª[Áï ·©Å©¿É¼Ç½ºÆ®¸µ]À» ³Ö´Â´Ù. } }; { // socket options... if(item_rule_info.IsEnableSocket()) xml.AddChildElemEx("SocketNum", item_slot.GetSocketNum()); //¼ÒÄϳѹö else xml.AddChildElemEx("SocketNum", 0); }; { // socket options detailed... int attr_index = 0; BYTE attr_value = 0; eATTR_TYPE attr_type = eATTR_TYPE_INVALID; int number_of_options = 0; BYTE upperbound = 0; eSOCKET_LEVEL level = SOCKETLV_LOW; char temp_buffer[256]; int buffer_offset = 0; char buffer[1024]; buffer[0] = '\0'; if(item_rule_info.IsEnableSocket() == 0) { xml.AddChildElem("SOCKET", buffer); } else { buffer_offset += _snprintf(&buffer[buffer_offset], _countof(buffer) - buffer_offset, "[ "); upperbound = (BYTE)item_slot.GetSocketNum(); for(int socket_inc = SOCKET_1; socket_inc < upperbound; ++socket_inc) { eSOCKET sock = (eSOCKET)socket_inc; attr_type = item_slot.GetSocketAttr(sock); if(attr_type == eATTR_TYPE_INVALID) continue; level = item_slot.GetSocketAttrLevel(sock); attr_value = item_slot.GetSocketAttrValue(sock); const sSOCKET_OPTION* option = item_slot.GetSocketAttrDesc(sock); if(option == 0) continue; GetStringByCode(option->m_NCode, temp_buffer, _countof(temp_buffer)); attr_index = option->m_AttrIndex; const char* socket_string = root_->ConvertSocketType(sock).c_str(); //¼ÒÄÏ, ÅØ½ºÆ®, º§·ù, À妽º,·¹º§ buffer_offset += _snprintf(&buffer[buffer_offset], _countof(buffer) - buffer_offset, "%s:%s:%d:%d:%d ", socket_string, temp_buffer, attr_value, attr_index, level); ++number_of_options; } buffer_offset += _snprintf(&buffer[buffer_offset], _countof(buffer) - buffer_offset, "]"); if(number_of_options != 0) buffer[0] = '\0'; xml.AddChildElem("SOCKET", buffer); //À§¿¡¼­ ¸¸µç ½ºÆ®¸µ°ª[Áï ·©Å©¿É¼Ç½ºÆ®¸µ]À» ³Ö´Â´Ù. } }; _Serialize_LimitedItem(true, xml, item_rule_info, const_cast(item_slot)); return true; } BOOLEAN CSunOnlineItem::EncodeItem(CMarkupArchive& xml, SCItemSlot& item_slot, POSTYPE* item_pos_out) { XmlElemStack stack_item(false, xml, "ITEM"); static std::string stl_temp; char buffer[1024]; SLOTCODE item_code = 0; if(xml.FindGetChildData("Code", item_code) == false) return false; if(item_code == 0) return false; item_slot.Clear(); item_slot.SetCode(item_code); const nsSlot::ItemRuleInfo& item_rule_info = item_slot.GetItemRuleInfo(); if(item_rule_info.is_valid_item == 0) return false; const BASE_ITEMINFO* item_info = item_slot.GetItemInfo(); POSTYPE item_pos = INVALID_POSTYPE_VALUE; if(xml.FindGetChildData("Pos", item_pos) == false) return false; *item_pos_out = item_pos; item_slot.SetPos(item_pos); // skip name BOOLEAN blocked = 0; if(xml.FindGetChildData("Block", blocked) == false) return false; //BUILD_KOREA_061211-- eCHARGE_SUB_TYPE charge_sub_type = eCHARGE_SUB_GENERAL; { //WORD item_type = 0; //WORD sub_type = 0; //BYTE charge_type = 0; BYTE charge_sub_type_temp = 0; //if(xml.FindGetChildData("Type", item_type) == false) // return false; //if(xml.FindGetChildData("SubType", sub_type) == false) // return false; //if(xml.FindGetChildData("ChargeType", charge_type) == false) // return false; if(xml.FindGetChildData("ChargeSubType", charge_sub_type_temp) == false) return false; charge_sub_type = (eCHARGE_SUB_TYPE)charge_sub_type_temp; //SetItemChargeExpireTime( ChargeSubType, slot, xml, sTemp.c_str() ); }; { BYTE db_type; if(xml.FindGetChildData("DBType", db_type) == false) return false; item_slot.SetType(db_type); DBSERIAL dbserial; if(xml.FindGetChildData("Serial", dbserial) == false) return false; item_slot.SetSerial(dbserial); BOOLEAN with_duration = 0; if(xml.FindGetChildData("IsDura", with_duration) == false) return false; if(item_slot.WithDura() != !!with_duration) return false; BYTE temp_value = 0; if(xml.FindGetChildData("Dura", temp_value) == false) return false; if(with_duration) item_slot.SetDura(temp_value); else item_slot.SetNum(temp_value); } #ifdef __NA_1247_POSSESSION_ITEM { BOOLEAN is_possession_type = 0; if(xml.FindGetChildData("IsPossessionType", is_possession_type) == false) return false; if(is_possession_type) { BOOLEAN is_possession = 0; if(xml.FindGetChildData("IsPossession", is_possession) == false) return false; if(is_possession) item_slot.SetIdentifyPossession(true); } #ifdef __NA_0_POSSESSION_ITEM_DROP BOOLEAN is_destroyed = false; if(xml.FindGetChildData("IsDestroyItem", is_destroyed) == false) return false; if(is_destroyed) item_slot.SetDestroyItem(true); #endif } #endif // (NOTE) element°¡ Á¸ÀçÇØ¾ß ÇÏ´Â ºÎºÐÀÌ ÀÖ´ÂÁö¶ó filteringÀ» ¼öÇàÇÏÁö ¾Ê´Â´Ù. _Serialize_EtherWeapon(false, xml, item_rule_info, const_cast(item_slot)); _Serialize_PetItem(false, xml, item_rule_info, const_cast(item_slot)); if(item_rule_info.IsEnableTimer()) { stl_temp.resize(0); if(xml.FindGetChildData("ChargeExpireTime", stl_temp) == false) return false; BOOLEAN is_progress = 0; BOOLEAN is_expired = 0; BOOLEAN is_wait_time = 0; if(xml.FindGetChildData("ChargeOnUse", is_progress) == false) return false; if(xml.FindGetChildData("IsExpiredTime", is_expired) == false) return false; if(xml.FindGetChildData("IsExpiredWaitTime", is_wait_time) == false) return false; if(is_progress) item_slot.SetProgressTime(!!is_progress); if(is_expired) item_slot.SetExpiredTime(!!is_expired); if(is_wait_time) item_slot.SetExpiredWaitTime(!!is_wait_time); BOOST_STATIC_WARNING(0); //SetItemChargeExpireTime(charge_sub_type, item_slot, xml, stl_temp.c_str()); char time_string[32]; strncpy(time_string, stl_temp.c_str(), _countof(time_string)); time_string[_countof(time_string) - 1] = '\0'; if(item_rule_info.is_fate) _Serialize_FateItem(false, xml, item_rule_info, item_slot, time_string); } { //divine BOOLEAN is_divine = false; if(xml.FindGetChildData("IsDivine", is_divine) == false) return false; if(is_divine) item_slot.SetSet(is_divine); }; if(item_rule_info.IsEnableEnchant()) { //enchant BYTE enchant = 0; if(xml.FindGetChildData("Enchant", enchant) == false) return false; if(enchant) item_slot.SetEnchant(enchant); }; if(item_rule_info.IsEnableExtraOption()) { //extra option ExtraStoneOptionInfoParser* pExtraStoneParser = ExtraStoneOptionInfoParser::Instance(); const sEXTRASTONE_OPT_INFO* pInfo = pExtraStoneParser->GetExtraStoneOptionInfo(item_info->m_wType /*, item_slot.GetItemInfo()->m_LV*/); if(pInfo) { int extra_option_index = 0; if(xml.FindGetChildData("NOptionValue", extra_option_index) == false) return false; item_slot.SetNOptionAttr(extra_option_index); } }; eRANK rank = RANK_E; { stl_temp.resize(0); if(xml.FindGetChildData("RankType", stl_temp) == false) return false; rank = root_->ConvertRankType(stl_temp); item_slot.SetRank(rank); }; if(rank != RANK_E) { stl_temp.resize(0); if(xml.FindGetChildData("RANK", stl_temp) == false) return false; std::string::size_type length = stl_temp.length(); if(length == 0 || _countof(buffer) <= length) return false; strncpy(buffer, stl_temp.c_str(), _countof(buffer)); buffer[_countof(buffer) - 1] = '\0'; char* token = strtok(buffer, "[]"); int count = 0; while(token != 0) { ++count; strncpy(buffer, token, _countof(buffer)); token = strtok(NULL, "[]"); } if(count > 1) { _LOG(__FUNCTION__"|Msg=invalid format rank option|"); __asm { int 3 }; return false; } typedef char* Infos[4]; //rank option args "Rank:Name:val:val" typedef Infos Tokens[RANK_MAX]; Tokens tokens = { 0, }; count = 0; token = strtok(buffer, " "); while(token != 0) { tokens[count++][0] = token; token = strtok(NULL, " "); } // stack overrun if(_countof(tokens) < count) { _LOG(__FUNCTION__"|Msg=invalid format rank option numbers|"); __asm { int 3 }; return false; } int upperbound = count; if(upperbound != 0) { // rank°¡ Àִµ¥, count==0À̸é??? int offset = 0; for(count = 0 ; count < upperbound; ++upperbound) { Infos& rank_infos = tokens[count]; token = strtok(rank_infos[count], ":"); while(token != 0) { rank_infos[offset++] = token; token = strtok(NULL, ":"); } if(_countof(rank_infos) < offset) { _LOG(__FUNCTION__"|Msg=invalid format rank separated option numbers|"); __asm { int 3 }; return false; } eRANK current_rank = root_->ConvertRankType(rank_infos[0]); int string_index = STRTBL_PARSER1->GetCodeByString(rank_infos[1]); int attr_value = atoi(rank_infos[2]); int attr_index = atoi(rank_infos[3]); if(_countof(g_ITEM_OPTION) <= attr_index) { _LOG(__FUNCTION__"|Msg=invalid format rank attributes index|index=%d|", attr_index); __asm { int 3 }; return false; } RankOptionParser* pRankOptionParser = RankOptionParser::Instance(); sRANK_OPTION* option = pRankOptionParser->GetRankOption(item_info->m_wType, attr_index); BOOST_STATIC_WARNING(0); //ÆÄ¼­ÀÇ °ªÀ» ¼³Á¤ÁßÀÌ´Ù... Á¤»óÀÎ °Ç°¡? if(option) { option->m_iOptionIndex = attr_index; if(string_index > 0) option->m_OptionNCode = string_index; option->m_Value[current_rank] = attr_value; item_slot.SetRank(current_rank); item_slot.SetRankAttr(current_rank, option); } } //end 'for' } //end 'if exist ranks' } //end 'if exist rank' BYTE number_of_sockets = 0; if(item_rule_info.IsEnableSocket()) { if(xml.FindGetChildData("SocketNum", number_of_sockets) == false) return false; if(number_of_sockets) item_slot.SetSocketNum(number_of_sockets); } if(number_of_sockets) { stl_temp.resize(0); if(xml.FindGetChildData("SOCKET", stl_temp) == false) return false; char buffer[1024]; std::string::size_type length = stl_temp.length(); if(length == 0 || _countof(buffer) <= length) return false; strncpy(buffer, stl_temp.c_str(), _countof(buffer)); buffer[_countof(buffer) - 1] = '\0'; char* token = strtok(buffer, "[]"); int count = 0; while(token != 0) { ++count; strncpy(buffer, token, _countof(buffer)); token = strtok(NULL, "[]"); } if(count > 1) { _LOG(__FUNCTION__"|Msg=invalid format rank option|"); __asm { int 3 }; return false; } typedef char* Infos[5]; //socket option args "SocketNo:Name:value:index:level" typedef Infos Tokens[SOCKET_MAX]; Tokens tokens = { 0, }; count = 0; token = strtok(buffer, " "); while(token != 0) { tokens[count++][0] = token; token = strtok(NULL, " "); } // stack overrun if(_countof(tokens) < count) { _LOG(__FUNCTION__"|Msg=invalid format socket option numbers|"); __asm { int 3 }; return false; } int upperbound = count; if(upperbound != 0) { // rank°¡ Àִµ¥, count==0À̸é??? int offset = 0; for(count = 0 ; count < upperbound; ++upperbound) { Infos& socket_infos = tokens[count]; token = strtok(socket_infos[count], ":"); while(token != 0) { socket_infos[offset++] = token; token = strtok(NULL, ":"); } if(_countof(socket_infos) < offset) { _LOG(__FUNCTION__"|Msg=invalid format socket separated option numbers|"); __asm { int 3 }; return false; } eSOCKET current_sock = root_->ConvertSocketType(socket_infos[0]); int string_index = STRTBL_PARSER1->GetCodeByString(socket_infos[1]); int attr_value = atoi(socket_infos[2]); int attr_index = atoi(socket_infos[3]); int sock_level = atoi(socket_infos[4]); if(_countof(g_ITEM_OPTION) <= attr_index) { _LOG(__FUNCTION__"|Msg=invalid format socket attributes index|index=%d|", attr_index); __asm { int 3 }; return false; } const sSOCKET_OPTION* option_c = SocketOptionParser::Instance()->GetSocketOption(attr_index); sSOCKET_OPTION* option = const_cast(option_c); BOOST_STATIC_WARNING(0); //ÆÄ¼­ÀÇ °ªÀ» ¼³Á¤ÁßÀÌ´Ù... Á¤»óÀÎ °Ç°¡? if(option) { option->m_AttrIndex = attr_index; if(string_index > 0) option->m_NCode = string_index; option->m_iValue[current_sock] = attr_value; item_slot.SetSocketAttr(current_sock, (eSOCKET_LEVEL)sock_level, option); } } //end 'for' } //end 'if exist sockets' } _Serialize_LimitedItem(false, xml, item_rule_info, item_slot); return true; } #endif //__NA000000_090906_SOLAR_SLOT_UPDATE_VER6__