diff --git a/src/game/char.cpp b/src/game/char.cpp index 4d73434..1b3dbfa 100644 --- a/src/game/char.cpp +++ b/src/game/char.cpp @@ -6010,13 +6010,13 @@ void CHARACTER::EffectPacket(int enumEffectType) PacketAround(&p, sizeof(TPacketGCSpecialEffect)); } -void CHARACTER::SpecificEffectPacket(const char filename[MAX_EFFECT_FILE_NAME]) +void CHARACTER::SpecificEffectPacket(const std::string& stEffectName) { TPacketGCSpecificEffect p; p.header = HEADER_GC_SPECIFIC_EFFECT; p.vid = GetVID(); - memcpy (p.effect_file, filename, MAX_EFFECT_FILE_NAME); + strlcpy(p.effect_file, stEffectName.c_str(), sizeof(p.effect_file)); PacketAround(&p, sizeof(TPacketGCSpecificEffect)); } diff --git a/src/game/char.h b/src/game/char.h index 8d52d56..6779b3a 100644 --- a/src/game/char.h +++ b/src/game/char.h @@ -1091,7 +1091,7 @@ class CHARACTER : public CEntity, public CFSM, public CHorseRider // void PotionPacket(int iPotionType); void EffectPacket(int enumEffectType); - void SpecificEffectPacket(const char filename[128]); + void SpecificEffectPacket(const std::string& stEffectName); // ADD_MONSTER_REFINE bool DoRefine(LPITEM item, bool bMoneyOnly = false); diff --git a/src/game/char_battle.cpp b/src/game/char_battle.cpp index 3817eac..d962cff 100644 --- a/src/game/char_battle.cpp +++ b/src/game/char_battle.cpp @@ -3195,7 +3195,7 @@ LPCHARACTER CHARACTER::GetNearestVictim(LPCHARACTER pkChr) LPCHARACTER pAttacker = CHARACTER_MANAGER::instance().Find(c_VID); - if (!pAttacker) + if (!pAttacker || pAttacker->IsDead()) continue; if (pAttacker->IsAffectFlag(AFF_EUNHYUNG) || diff --git a/src/game/cmd_gm.cpp b/src/game/cmd_gm.cpp index 28c13e6..1efb680 100644 --- a/src/game/cmd_gm.cpp +++ b/src/game/cmd_gm.cpp @@ -4082,28 +4082,28 @@ ACMD (do_item_full_set) { item = ITEM_MANAGER::instance().CreateItem(11699); - if (!item || !item->EquipTo(ch, item->FindEquipCell(ch))) + if (item && !item->EquipTo(ch, item->FindEquipCell(ch))) M2_DESTROY_ITEM(item); item = ITEM_MANAGER::instance().CreateItem(13049); - if (!item || !item->EquipTo(ch, item->FindEquipCell(ch))) + if (item && !item->EquipTo(ch, item->FindEquipCell(ch))) M2_DESTROY_ITEM(item); item = ITEM_MANAGER::instance().CreateItem(15189 ); - if (!item || !item->EquipTo(ch, item->FindEquipCell(ch))) + if (item && !item->EquipTo(ch, item->FindEquipCell(ch))) M2_DESTROY_ITEM(item); item = ITEM_MANAGER::instance().CreateItem(189 ); - if (!item || !item->EquipTo(ch, item->FindEquipCell(ch))) + if (item && !item->EquipTo(ch, item->FindEquipCell(ch))) M2_DESTROY_ITEM(item); item = ITEM_MANAGER::instance().CreateItem(12529 ); - if (!item || !item->EquipTo(ch, item->FindEquipCell(ch))) + if (item && !item->EquipTo(ch, item->FindEquipCell(ch))) M2_DESTROY_ITEM(item); item = ITEM_MANAGER::instance().CreateItem(14109 ); - if (!item || !item->EquipTo(ch, item->FindEquipCell(ch))) + if (item && !item->EquipTo(ch, item->FindEquipCell(ch))) M2_DESTROY_ITEM(item); item = ITEM_MANAGER::instance().CreateItem(17209 ); - if (!item || !item->EquipTo(ch, item->FindEquipCell(ch))) + if (item && !item->EquipTo(ch, item->FindEquipCell(ch))) M2_DESTROY_ITEM(item); item = ITEM_MANAGER::instance().CreateItem(16209 ); - if (!item || !item->EquipTo(ch, item->FindEquipCell(ch))) + if (item && !item->EquipTo(ch, item->FindEquipCell(ch))) M2_DESTROY_ITEM(item); } break; @@ -4111,28 +4111,28 @@ ACMD (do_item_full_set) { item = ITEM_MANAGER::instance().CreateItem(11299); - if (!item || !item->EquipTo(ch, item->FindEquipCell(ch))) + if (item && !item->EquipTo(ch, item->FindEquipCell(ch))) M2_DESTROY_ITEM(item); item = ITEM_MANAGER::instance().CreateItem(13049); - if (!item || !item->EquipTo(ch, item->FindEquipCell(ch))) + if (item && !item->EquipTo(ch, item->FindEquipCell(ch))) M2_DESTROY_ITEM(item); item = ITEM_MANAGER::instance().CreateItem(15189 ); - if (!item || !item->EquipTo(ch, item->FindEquipCell(ch))) + if (item && !item->EquipTo(ch, item->FindEquipCell(ch))) M2_DESTROY_ITEM(item); item = ITEM_MANAGER::instance().CreateItem(3159 ); - if (!item || !item->EquipTo(ch, item->FindEquipCell(ch))) + if (item && !item->EquipTo(ch, item->FindEquipCell(ch))) M2_DESTROY_ITEM(item); item = ITEM_MANAGER::instance().CreateItem(12249 ); - if (!item || !item->EquipTo(ch, item->FindEquipCell(ch))) + if (item && !item->EquipTo(ch, item->FindEquipCell(ch))) M2_DESTROY_ITEM(item); item = ITEM_MANAGER::instance().CreateItem(14109 ); - if (!item || !item->EquipTo(ch, item->FindEquipCell(ch))) + if (item && !item->EquipTo(ch, item->FindEquipCell(ch))) M2_DESTROY_ITEM(item); item = ITEM_MANAGER::instance().CreateItem(17109 ); - if (!item || !item->EquipTo(ch, item->FindEquipCell(ch))) + if (item && !item->EquipTo(ch, item->FindEquipCell(ch))) M2_DESTROY_ITEM(item); item = ITEM_MANAGER::instance().CreateItem(16109 ); - if (!item || !item->EquipTo(ch, item->FindEquipCell(ch))) + if (item && !item->EquipTo(ch, item->FindEquipCell(ch))) M2_DESTROY_ITEM(item); } break; @@ -4140,28 +4140,28 @@ ACMD (do_item_full_set) { item = ITEM_MANAGER::instance().CreateItem(11899); - if (!item || !item->EquipTo(ch, item->FindEquipCell(ch))) + if (item && !item->EquipTo(ch, item->FindEquipCell(ch))) M2_DESTROY_ITEM(item); item = ITEM_MANAGER::instance().CreateItem(13049); - if (!item || !item->EquipTo(ch, item->FindEquipCell(ch))) + if (item && !item->EquipTo(ch, item->FindEquipCell(ch))) M2_DESTROY_ITEM(item); item = ITEM_MANAGER::instance().CreateItem(15189 ); - if (!item || !item->EquipTo(ch, item->FindEquipCell(ch))) + if (item && !item->EquipTo(ch, item->FindEquipCell(ch))) M2_DESTROY_ITEM(item); item = ITEM_MANAGER::instance().CreateItem(7159 ); - if (!item || !item->EquipTo(ch, item->FindEquipCell(ch))) + if (item && !item->EquipTo(ch, item->FindEquipCell(ch))) M2_DESTROY_ITEM(item); item = ITEM_MANAGER::instance().CreateItem(12669 ); - if (!item || !item->EquipTo(ch, item->FindEquipCell(ch))) + if (item && !item->EquipTo(ch, item->FindEquipCell(ch))) M2_DESTROY_ITEM(item); item = ITEM_MANAGER::instance().CreateItem(14109 ); - if (!item || !item->EquipTo(ch, item->FindEquipCell(ch))) + if (item && !item->EquipTo(ch, item->FindEquipCell(ch))) M2_DESTROY_ITEM(item); item = ITEM_MANAGER::instance().CreateItem(17209 ); - if (!item || !item->EquipTo(ch, item->FindEquipCell(ch))) + if (item && !item->EquipTo(ch, item->FindEquipCell(ch))) M2_DESTROY_ITEM(item); item = ITEM_MANAGER::instance().CreateItem(16209 ); - if (!item || !item->EquipTo(ch, item->FindEquipCell(ch))) + if (item && !item->EquipTo(ch, item->FindEquipCell(ch))) M2_DESTROY_ITEM(item); } break; @@ -4169,31 +4169,35 @@ ACMD (do_item_full_set) { item = ITEM_MANAGER::instance().CreateItem(11499); - if (!item || !item->EquipTo(ch, item->FindEquipCell(ch))) + if (item && !item->EquipTo(ch, item->FindEquipCell(ch))) M2_DESTROY_ITEM(item); item = ITEM_MANAGER::instance().CreateItem(13049); - if (!item || !item->EquipTo(ch, item->FindEquipCell(ch))) + if (item && !item->EquipTo(ch, item->FindEquipCell(ch))) M2_DESTROY_ITEM(item); item = ITEM_MANAGER::instance().CreateItem(15189 ); - if (!item || !item->EquipTo(ch, item->FindEquipCell(ch))) + if (item && !item->EquipTo(ch, item->FindEquipCell(ch))) M2_DESTROY_ITEM(item); item = ITEM_MANAGER::instance().CreateItem(1139 ); - if (!item || !item->EquipTo(ch, item->FindEquipCell(ch))) + if (item && !item->EquipTo(ch, item->FindEquipCell(ch))) M2_DESTROY_ITEM(item); item = ITEM_MANAGER::instance().CreateItem(12389 ); - if (!item || !item->EquipTo(ch, item->FindEquipCell(ch))) + if (item && !item->EquipTo(ch, item->FindEquipCell(ch))) M2_DESTROY_ITEM(item); item = ITEM_MANAGER::instance().CreateItem(14109 ); - if (!item || !item->EquipTo(ch, item->FindEquipCell(ch))) + if (item && !item->EquipTo(ch, item->FindEquipCell(ch))) M2_DESTROY_ITEM(item); item = ITEM_MANAGER::instance().CreateItem(17189 ); - if (!item || !item->EquipTo(ch, item->FindEquipCell(ch))) + if (item && !item->EquipTo(ch, item->FindEquipCell(ch))) M2_DESTROY_ITEM(item); item = ITEM_MANAGER::instance().CreateItem(16189 ); - if (!item || !item->EquipTo(ch, item->FindEquipCell(ch))) + if (item && !item->EquipTo(ch, item->FindEquipCell(ch))) M2_DESTROY_ITEM(item); } break; + + default: + ch->ChatPacket(CHAT_TYPE_INFO, "Full set is not available for your job"); + break; } } diff --git a/src/game/desc.cpp b/src/game/desc.cpp index 9c281b4..0016c57 100644 --- a/src/game/desc.cpp +++ b/src/game/desc.cpp @@ -428,6 +428,13 @@ void DESC::Packet(const void * c_pvData, int iSize) if (m_iPhase == PHASE_CLOSE) // 끊는 상태면 보내지 않는다. return; + if (!m_lpOutputBuffer) + { + sys_err("DESC::Packet: Trying to send packet but output buffer is NULL! (DESC: %p)", this); + SetPhase(PHASE_CLOSE); + return; + } + if (m_stRelayName.length() != 0) { // Relay 패킷은 암호화하지 않는다. diff --git a/src/game/guild.cpp b/src/game/guild.cpp index 1e1a771..9e7ce59 100644 --- a/src/game/guild.cpp +++ b/src/game/guild.cpp @@ -2013,13 +2013,13 @@ void CGuild::Invite( LPCHARACTER pchInviter, LPCHARACTER pchInvitee ) TPacketGCGuild p; p.header = HEADER_GC_GUILD; - p.size = sizeof(p) + sizeof(DWORD) + GUILD_NAME_MAX_LEN + 1; + p.size = sizeof(p) + sizeof(DWORD) + GUILD_NAME_MAX_LEN; p.subheader = GUILD_SUBHEADER_GC_GUILD_INVITE; TEMP_BUFFER buf; buf.write( &p, sizeof(p) ); buf.write( &gid, sizeof(DWORD) ); - buf.write( GetName(), GUILD_NAME_MAX_LEN + 1 ); + buf.write( GetName(), GUILD_NAME_MAX_LEN ); pchInvitee->GetDesc()->Packet( buf.read_peek(), buf.size() ); } diff --git a/src/game/item_manager.cpp b/src/game/item_manager.cpp index 489ece7..585c13f 100644 --- a/src/game/item_manager.cpp +++ b/src/game/item_manager.cpp @@ -469,21 +469,31 @@ void ITEM_MANAGER::SaveSingleItem(LPITEM item) void ITEM_MANAGER::Update() { - std::unordered_set::iterator it = m_set_pkItemForDelayedSave.begin(); - std::unordered_set::iterator this_it; - - while (it != m_set_pkItemForDelayedSave.end()) + for (auto it = m_set_pkItemForDelayedSave.begin(); it != m_set_pkItemForDelayedSave.end();) { - this_it = it++; - LPITEM item = *this_it; - - // SLOW_QUERY 플래그가 있는 것은 종료시에만 저장한다. - if (item->GetOwner() && IS_SET(item->GetFlag(), ITEM_FLAG_SLOW_QUERY)) + LPITEM item = *it; + if (!item) + { + sys_err("nullptr item, erasing from delayed save."); + it = m_set_pkItemForDelayedSave.erase(it); continue; + } + + if (!FindByVID(item->GetVID())) + { + sys_err("Invalid item(%u), erasing from delayed save.", item->GetVID()); + it = m_set_pkItemForDelayedSave.erase(it); + continue; + } + + if (item->GetOwner() && IS_SET(item->GetFlag(), ITEM_FLAG_SLOW_QUERY)) + { + ++it; // just skip don't erase + continue; + } SaveSingleItem(item); - - m_set_pkItemForDelayedSave.erase(this_it); + it = m_set_pkItemForDelayedSave.erase(it); } } @@ -619,28 +629,29 @@ TItemTable * ITEM_MANAGER::GetTable(DWORD vnum) int ITEM_MANAGER::RealNumber(DWORD vnum) { - int bot, top, mid; + if (m_vec_prototype.empty()) + return -1; - bot = 0; - top = m_vec_prototype.size(); + int left = 0; + int right = m_vec_prototype.size() - 1; - TItemTable * pTable = &m_vec_prototype[0]; - - while (1) + while (left <= right) { - mid = (bot + top) >> 1; + int mid = (left + right) / 2; - if ((pTable + mid)->dwVnum == vnum) - return (mid); + if (mid < 0 || mid >= static_cast(m_vec_prototype.size())) + return -1; - if (bot >= top) - return (-1); + if (m_vec_prototype[mid].dwVnum == vnum) + return mid; - if ((pTable + mid)->dwVnum > vnum) - top = mid - 1; - else - bot = mid + 1; + if (m_vec_prototype[mid].dwVnum > vnum) + right = mid - 1; + else + left = mid + 1; } + + return -1; } bool ITEM_MANAGER::GetVnum(const char * c_pszName, DWORD & r_dwVnum)