#include "stdafx.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "Character.h" #include "CharacterCreate.h" #include "SphereTree/CharSphereTree.h" // forward decl. void CheckDuplicatedItem(CCharacter& character); void SendItemDuplicatedLog(CSendStream& SendStream, unsigned __int64 dwItemSerial, Item::CItemOwnerInfo& itemOwnerInfo, unsigned long dwItemQty); void CCharacter::PrepareLogin() { // HP/MP¼¼ÆÃ m_CreatureStatus.m_nNowHP = m_DBData.m_Info.HP; m_CreatureStatus.m_nNowMP = m_DBData.m_Info.MP; // º¹»ç ¾ÆÀÌÅÛ °Ë»ç CheckDuplicatedItem(*this); // edith 2009.02.07 ¼®»óÀü À§Ä¡ ³»ÀÇ Áö¿ª¿¡¼­ ·Î±×ÀÎÇϴ°Š¹æÁö if (SERVER_ID::STONE_WAR1 <= CServerSetup::GetInstance().GetServerZone() && CServerSetup::GetInstance().GetServerZone() <= SERVER_ID::STONE_WAR3) { // ÁÂÇ¥ °Ë»ç if (!CCellManager::GetInstance().CheckPositionInZone(m_CurrentPos)) { if (CServerSetup::GetInstance().IsBattleGameServer()) { m_CurrentPos = CharCreate::BGServerStartPos[GetRace()][Math::Random::ComplexRandom(CharCreate::MAX_LOBBY_RESPAWN_POS)]; m_CurrentPos.m_fPointX += Math::Random::SimpleRandom(GetTickCount(), 20) - 10; m_CurrentPos.m_fPointZ += Math::Random::SimpleRandom(GetTickCount(), 20) - 10; } else { m_CurrentPos = CCharRespawnMgr::GetInstance().GetDefaultRespawnPos(GetNation()); } m_DBData.m_Pos.LastPoint.fPointX = m_CurrentPos.m_fPointX; m_DBData.m_Pos.LastPoint.fPointY = m_CurrentPos.m_fPointY; m_DBData.m_Pos.LastPoint.fPointZ = m_CurrentPos.m_fPointZ; } } // ºê·Îµåij½ºÆÃ µ¥ÀÌÅÍ Áغñ m_SerializeCharacterData.PrepareData(*this); m_SerializeCharacterData.ClearDeltaData(); SetOperationFlag(CHAR_INFO_LOADED); } bool CCharacter::Login() { if (NULL == m_lpGameClientDispatch) { return false; } CSendStream& SendStream = m_lpGameClientDispatch->GetSendStream(); /* #ifndef NO_GAMEGUARD // ·Î±×ÀÎ ÇϱâÀü¿¡ °ÔÀÓ°¡µå ó¸® // edith 2009.08.11 °ÔÀÓ°¡µå Å×½ºÆ® if (NULL != m_lpGameClientDispatch)// && 0 == GetAdminLevel()) { // edith 2009.08.11 °ÔÀÓ°¡µå 2.5 ¾÷±×·¹À̵å // if (false == m_lpGameClientDispatch->IsAuth()) // { // ERRLOG1(g_Log, "CID:0x%08x °ÔÀÓ °¡µå ÀÎÁõ Äڵ带 º¸³»Áö¾Ê¾Æ ¿¬°áÀ» ²÷½À´Ï´Ù.", GetCID()); // m_lpGameClientDispatch->Disconnect(); // return false; // } GG_AUTH_DATA* lpAuthData = NULL; if (false == m_lpGameClientDispatch->GetAuthQuery(&lpAuthData)) { ERRLOG1(g_Log, "CID:0x%08x °ÔÀÓ °¡µå ÀÎÁõ ÄÚµå(2) üũ¿¡ ½ÇÆÐÇÏ¿© ¿¬°áÀ» ²÷½À´Ï´Ù.", GetCID()); m_lpGameClientDispatch->Disconnect(); return false; } GameClientSendPacket::SendCSAuth(SendStream, GetCID(), m_lpGameClientDispatch->GetAuthCode(), lpAuthData, PktBase::NO_SERVER_ERR); } #endif */ // DELETE_ME : ´õÀÌ»ó Ŭ¶óÀÌ¾ðÆ®°¡ ¹ÝÀü ¸ðµå·ÎÀÇ º¯°æÀº ºÒ°¡´ÉÇÏ´Ù. °³³ä¸¸ ³²¾ÆÀÖÀ» »Ó. (2005-05-31 by ·Îµò) /* // ÀüÀï ¸ðµå Á¦ÇÑ if (SERVER_ID::ZONE12 == CServerSetup::GetInstance().GetServerZone() || SERVER_ID::CAPITAL == CServerSetup::GetInstance().GetServerZone()) { m_PeaceMode.m_bPeace = true; } else { m_PeaceMode.m_bPeace = false; } SetPeaceMode(m_PeaceMode, false); GameClientSendPacket::SendCharPeaceMode(SendStream, m_dwCID, 0, m_PeaceMode.m_bPeace, 0); */ // ¹èƲ ±×¶ó¿îµå ¼­¹ö±º¿¡¼­ ·¹º§Àº 40À¸·Î °íÁ¤ if (SERVER_ID::BATTLE_SERVER == CServerSetup::GetInstance().GetServerZone()) { // ·¹º§Àº 40À¸·Î °íÁ¤ while (static_cast(m_CreatureStatus.m_nLevel) < 40) { if (false == IncrementExp(static_cast( EXP::ExpTable[m_CreatureStatus.m_nLevel - 1]))) { break; } } } // Cell ÀÏ ¼³Á¤µÇÁö ¾ÊÀº »óÅÂÀ̹ǷΠMoveTo ÇÔ¼ö¸¦ Çѹø È£ÃâÇØÁØ´Ù. MoveTo(GetCurrentPos(), false); // edith 2009.06.13 16¹ø Á¸ / 17¹ø Á¸¿¡¼­ ¹«Àû½Ã°£ Á¶Á¤ int InvincibleTime = 30; if (SERVER_ID::STONE_WAR1 <= CServerSetup::GetInstance().GetServerZone() && CServerSetup::GetInstance().GetServerZone() <= SERVER_ID::STONE_WAR3) { InvincibleTime = 15; char cZone = CServerSetup::GetInstance().GetServerZone(); // edith 2009.06.13 ¼®»óÀü¿¡¼­ ·Î±×ÀÎÇÒ °æ¿ì ½ºÅ¸ÆÃ Æ÷ÀÎÆ®¿¡¼­ ¸®½ºÆùµÇ¾î¼­ ½ÃÀÛ // À§Ä¡¸¦ À̵¿½ÃŰ·Á¸é MovePos Áï ¿öÇÁ¸¦ ÀÌ¿ëÇØ¼­ ÇØ´çÁÂÇ¥·Î °­Á¦À̵¿½ÃŲ´Ù. const Position targetPos = CCharRespawnMgr::GetInstance().GetTownRespawnPos(cZone, GetNation()); MovePos(targetPos, cZone, false); // Á×Àº »óÅÂ¸é ¸®½ºÆù ½ÃŲ´Ù. if (0 == m_CreatureStatus.m_nNowHP) { Respawn(); } } // ·Î±×Àνà 30Ãʰ£ ¹«Àû Skill::CAddSpell(CSpell::Spell_Info(Skill::CProcessTable::ProcessInfo::m_NullProtoType, this, Skill::SpellType::MAGICAL_SPELL, Skill::SpellID::Invincible, 1, InvincibleTime))(this); // ¿ùµå ¿þÆùÀÌ Á¸ÀçÇÏ¸é ¿ùµå ¿þÆù ÀÎæƮ Àû¿ë CCamp* lpWorldWeapon = CSiegeObjectMgr::GetInstance().GetWorldWeapon(); if (lpWorldWeapon) { AddWorldWeaponEnchant(reinterpret_cast(lpWorldWeapon), lpWorldWeapon->GetNation()); } // DB¿¡¼­ ½ºÆçÀ» Àоî¿Í ´Ù½Ã °É¾îÁØ´Ù. const SPELL spell = GetSpell(); GetSpellMgr().SetSpell(spell); // ±æµå Á¤º¸¸¦ ÁØ´Ù. CGuild* lpGuild = 0; if (0 != GetGID() && 0 != (lpGuild = CGuildMgr::GetInstance().GetGuild(GetGID()))) { unsigned short wError = PktBase::NO_SERVER_ERR; unsigned char cTitle = lpGuild->GetTitle(m_dwCID); if (Guild::NONE == cTitle) { wError = PktBase::SERVER_ERROR; } GameClientSendPacket::SendCharMyGuildInfo(SendStream, lpGuild->GetGold(), lpGuild->GetRight(), cTitle, wError); } // ¼º Á¤º¸ Àü¼Û GameClientSendPacket::SendCharCastleInfo(SendStream); // °ÔÀÓ ½Ã°£ Á¤º¸ Àü¼Û GameClientSendPacket::SendCharGameTimeInfo(SendStream); // ±æµå ¿ä»õ Á¤º¸ Àü¼Û GameClientSendPacket::SendCharCampInfo(SendStream); // CASTLE_TODO : ¼ºÀÌ ±æµå ¼ÒÀ¯°¡ ¾Æ´Ï¹Ç·Î ÀÏ´Ü ¸·¾ÆµÐ´Ù. // ¸®½ºÆù ¼Óµµ Çâ»ó Àû¿ë // if (0 != GetGID()) // { // Castle::CCastle* lpCastle = Castle::CCastleMgr::GetInstance().GetCastleByGID(GetGID()); // if (lpCastle) // { // CSiegeObject* lpEmblem = lpCastle->GetCastleEmblem(); // if (lpEmblem && lpEmblem->GetUpgradeStep() > 0) // { // UpgradeRespawnSpeedByEmblem(lpEmblem->GetUpgradeType(), lpEmblem->GetUpgradeStep()); // } // } // } // ¿¤¸®Æ® º¸³Ê½º Á¤º¸ Àü¼Û GameClientSendPacket::SendCharEliteBonus(SendStream, GetEliteBonus()); // °ÅºÎ ¿É¼Ç Á¤º¸ Àü¼Û GameClientSendPacket::SendCharControlOption(SendStream, m_dwCID, m_RejectOption); // ¾îºô¸®Æ¼ Æ÷ÀÎÆ® ¾÷µ¥ÀÌÆ® UpdateUseAbilityPoint(); // edith 2008.06.03 °øÇåÈÆÀå Æ÷ÀÎÆ®È¿°ú // ÄÁÅÙÃ÷ : ´ÙÅ© Ä«³ª¹ø ±¹°¡ ÀüÀï if (true == CServerSetup::GetInstance().UseContents(GameRYL::STONE_BATTLE)) { // ±¹°¡ÀüÀï °øÇåÈÆÀå Æ÷ÀÎÆ® È¿°ú. if (CGameTimeMgr::GetInstance().IsRealmWarTime() && (SERVER_ID::STONE_WAR1 <= CServerSetup::GetInstance().GetServerZone() && CServerSetup::GetInstance().GetServerZone() <= SERVER_ID::STONE_WAR3)) { RealmSkill::RealmInchantAdd(this); } } // Admin ij¸¯ÅÍ¿¡´Â ¿¹¿Üó¸® (QA ÂÊ ¿äû). if (true == CServerSetup::GetInstance().UseContents(GameRYL::STONE_BATTLE)) { if(GetAdminLevel()) { goto lb_move; } } /* if (true == CServerSetup::GetInstance().UseContents(GameRYL::NEWZONE_ZONE9)) { if(GetAdminLevel()) { goto lb_move; } } */ // ±æµåÀü, ±¹°¡Àü Âü¿© ij¸¯ÅÍ´Â ÇØ´ç ½Ã°£¿¡ ·Î±×Àνà Á¸ À̵¿ 󸮸¦ ÇØÁØ´Ù. if (CGameTimeMgr::GetInstance().IsGuildWarTime() && (GetGuildWarFlag() == Creature::WAR_ON || GetGuildWarFlag() == Creature::WAR_INSTANCE)) { MoveToGuildWarZone(); } // °ø¼ºÀü Áß ·Î±×ÀÎÇÒ °æ¿ì °ø¼ºÃøÀº ¸®½ºÆù Áö¿ªÀ¸·Î À̵¿½ÃŲ´Ù. // edith 2008.07.17 ijÇÇÅ»Á¸¿¡ ·Î±×ÀÎÇߴµ¥ °ø¼º½Ã°£ÀÌ¸é ¸®½ºÆùÁö¿ªÀ¸·Î À̵¿ÇÔ. if(CServerSetup::GetInstance().GetServerZone() == SERVER_ID::CAPITAL) { if(CGameTimeMgr::GetInstance().IsSiegeWarTime()) { using namespace DBAgentPacketParse; SiegeMovePos(this); } } // ÄÁÅÙÃ÷ : ´ÙÅ© Ä«³ª¹ø ±¹°¡ ÀüÀï if (true == CServerSetup::GetInstance().UseContents(GameRYL::STONE_BATTLE)) { if ((CGameTimeMgr::GetInstance().IsRealmWarReadyTime() || CGameTimeMgr::GetInstance().IsRealmWarTime()) && (GetRealmWarFlag() == Creature::WAR_ON || GetRealmWarFlag() == Creature::WAR_INSTANCE) && (SERVER_ID::STONE_WAR1 < CServerSetup::GetInstance().GetServerZone() || CServerSetup::GetInstance().GetServerZone() > SERVER_ID::STONE_WAR3) ) { // ·¤¸§Àü ½Ã°£Àε¥ ÀüÅõÂü°¡°¡ µÇ¾îÀÖ°í.ÇÏÁö¸¸ 16¹øÀÌ ¾Æ´Ï´Ï °­Á¦·Î 16¹øÀ¸·Î À̵¿. MoveToRealmWarZone(); } if (CGameTimeMgr::GetInstance().IsRealmWarTime() && GetRealmWarFlag() == Creature::WAR_OFF && (SERVER_ID::STONE_WAR1 <= CServerSetup::GetInstance().GetServerZone() && CServerSetup::GetInstance().GetServerZone() <= SERVER_ID::STONE_WAR3)) { // edith 2008.07.08 Àï¿¡ Âü¿©¸¦ ¾ÈÇߴµ¥ 16¹ø Á¸À̰í.. ·¤¸§Àü ½Ã°£ÀÌ¸é °­Á¦ Âü¿© GET_SINGLE_DISPATCH(lpDBAgentDispatch, CDBAgentDispatch, CDBAgentDispatch::GetDispatchTable()); if (0 != lpDBAgentDispatch) { GameClientSendPacket::SendWarOnOff(lpDBAgentDispatch->GetSendStream(), GetCID(), GameTime::REALM, Creature::WAR_INSTANCE, 0); } // ÀüÀï½Ã°£¿¡ ·Î±×ÀÎÇߴµ¥ ¾ó·¡ ³»°¡ ¼®»óÀü ¸Ê¿¡¼­ ·Î±×ÀÎÀ» Çß¾î.. À̸£¸é ¸®½ºÆùÀ§Ä¡·Î °­Á¦À̵¿ÇØ.. // edith 2008.07.08 ÀüÀï¿¡ Âü°¡¾ÈÇÑ »ç¶÷ÀÌÁö¸¸ 16¹øÁ¸¿¡ Á¸ÀçÇÏ¸é ¸®½ºÆùÀ§Ä¡·Î °­Á¦ À̵¿½ÃŲ´Ù. // MoveToRealmWarZone(); } lb_move: // edith 2008.06.03 ¼®»ó ÀÎþƮȿ°ú // ´ÙÅ© Ä«³ª¹ø¿¡ ·Î±×Àνà if (SERVER_ID::STONE_WAR1 <= CServerSetup::GetInstance().GetServerZone() && CServerSetup::GetInstance().GetServerZone() <= SERVER_ID::STONE_WAR3) { // ¼®»ó Á¤º¸¸¦ º¸³»ÁØ´Ù. CCreatureManager::GetInstance().SendRealmStatueDisplayInfo(SendStream); bool bAddRealmStatueEnchant = false; if (true == CServerSetup::GetInstance().UseContents(GameRYL::STONE_BATTLE)) { // ±¹°¡ ÀüÀï ½Ã°£ÀÌ ¾Æ´Ï¶ó¸é, ¼®»ó ÀÎæƮ È¿°ú¸¦ °É¾îÁØ´Ù. if (!CGameTimeMgr::GetInstance().IsRealmWarTime()) { bAddRealmStatueEnchant = true; } } /* // °ø¼±Àü¿ë ¸Ê°ú ¼®»óÀü¿ë ¸ÊÀÌ µû·Î±â ¶§¹®¿¡ ÇØ´ç ·ÎÁ÷ ºÒÇÊ¿ä if (true == CServerSetup::GetInstance().UseContents(GameRYL::SIEGE)) { // °ø¼ºÀü ÄÁÅÙÃ÷ Æ÷ÇԽà °ø¼ºÀü ½Ã°£µµ ¾Æ´Ï¶ó¸é, ¼®»ó ÀÎæƮ È¿°ú¸¦ °É¾îÁØ´Ù. if (CGameTimeMgr::GetInstance().IsSiegeWarTime()) { bAddRealmStatueEnchant = false; } } */ /* // ¼®»ó ÀÎæƮ È¿°ú¸¦ Àû¿ëÇÒ ¼ö ÀÖ´Â »óȲÀ̶ó¸é.... if (bAddRealmStatueEnchant) { // edith 2008.06.03 ¼®»óÀüÀÌ ³¡³¯¶§ 11½Ã°£ ¹öÇÁ¸¦ °É¾îÁØ´Ù. CCreatureManager::GetInstance().AddRealmStatueEnchant(this); } */ } // ½Å±ÔÁ¸ ·Î±×Àνà else if (CServerSetup::GetInstance().GetServerZone() == SERVER_ID::ZONE5) { // »ý¸íÃàÃâ±â Á¤º¸¸¦ º¸³»ÁØ´Ù. CCreatureManager::GetInstance().SendRealmStatueDisplayInfo(SendStream); } } LOG_INOUT( const int MAX_LOG_BUFFER = 1024; char szBuffer[MAX_LOG_BUFFER]; unsigned long dwDispatchUID = m_lpGameClientDispatch->GetUID(); const SOCKADDR_IN& sockAddr = m_lpGameClientDispatch->GetRemoteAddr().get_addr_in(); _snprintf(szBuffer, MAX_LOG_BUFFER - 1, "UID:%d/CID:0x%08x(0x%p)/DispatchUID:%d/DispatchPointer:0x%p ·Î±×Àο¡ ¼º°øÇÏ¿´½À´Ï´Ù. " "¸î°¡Áö ±âº» Á¤º¸¸¦ Âï½À´Ï´Ù. %s(lev:%2d, exp:%016I64u) IP:%15s:%5u", m_dwUID, m_dwCID, this, dwDispatchUID, m_lpGameClientDispatch, m_DBData.m_Info.Name, m_DBData.m_Info.Level, m_DBData.m_Info.Exp, inet_ntoa(sockAddr.sin_addr), ntohs(sockAddr.sin_port)); szBuffer[MAX_LOG_BUFFER - 1] = 0; DETLOG0(g_Log, szBuffer); ); return true; } bool CCharacter::Logout(DBUpdateData::UpdateType eUpdateType) { // ¹èƲ±×¶ó¿îµåÀÇ °æ¿ì (Á×Àº »óŶó¸é) ¸®½ºÆù Å¥¿¡¼­ Á¦°Å if (SERVER_ID::ZONE3 == CServerSetup::GetInstance().GetServerZone()) { CCreatureManager::GetInstance().PopRespawnQueue(this); } // Á×¾ú´Âµ¥ ¸®½ºÆù ¾ÈÇÏ°í ·Î±×¾Æ¿ôÇϸé // ³»±¸µµ°¡ ¾È±ïÀÌ´Â ¹ö±×°¡ À־ ·Î±×¾Æ¿ôÇÒ¶§ ºÎȰÇÑ »óŰ¡ ¾Æ´Ï¸é ³»±¸µµ¸¦ ±ï¾Æ¹ö¸°´Ù. if(IsDead()) { switch(m_eLastDeadType) { case DEAD_BY_NONE: // ¿Ã ¼ö ¾øÀ½ case DEAD_BY_CHARACTER: // ij¸¯ÅÍ¿¡ ÀÇÇØ »ç¸Á break; case DEAD_BY_SUICIDE: // ÀÚ»ì // ÀÚ»ì½Ã ³»±¸µµ °¨¼Ò CalculateAllEquipDurability(DURABILITY_DECREASE_PERSENT_BY_SUICIDE); break; case DEAD_BY_MONSTER: // ¸ó½ºÅÍ¿¡ ÀÇÇØ »ç¸Á if (!CServerSetup::GetInstance().GetDeathPenaltyEvent()) { unsigned char cDecreasePersent = 0; if(m_AbilityValue[Skill::Type::AB_ENDUR_SHILD] != 0) cDecreasePersent = DURABILITY_DECREASE_PERSENT_BY_MONSTER*m_AbilityValue[Skill::Type::AB_ENDUR_SHILD]/100; // ¸ó½ºÅÍ¿¡°Ô Á×¾úÀ» ¶§ ³»±¸µµ °¨¼Ò CalculateAllEquipDurability(DURABILITY_DECREASE_PERSENT_BY_MONSTER-cDecreasePersent); } break; } } // ¿ùµå ¿þÆù ÀÎæƮ¸¦ Á¦°ÅÇÑ´Ù. ClearWorldWeaponEnchant(); // ¼º¹®À» ¸·°í ÀÖ´ø ÁßÀ̾ú´Ù¸é... ¼º¹® ¸·±â¸¦ Ãë¼ÒÇÑ´Ù. if (0 != m_dwProtectGateCID) { CCastleGate* lpGate = reinterpret_cast( CSiegeObjectMgr::GetInstance().GetSiegeObject(m_dwProtectGateCID) ); if (lpGate) { lpGate->DeleteProtectGate(this); // Ŭ¶óÀÌ¾ðÆ®¿¡°Ô Àü¼Û CGameClientDispatch* lpDispatch = GetDispatcher(); if (NULL != lpDispatch) { GameClientSendPacket::SendCharCastleCmd(lpDispatch->GetSendStream(), lpGate->GetCastleID(), lpGate->GetCID(), 0, 0, PktCastleCmd::CASTLE_GATE_PROTECT_CANCEL, PktCastleCmd::NO_SERVER_ERR); } } } // ¼¿ ·Î±×¾Æ¿ô if (NULL != m_CellPos.m_lpCell) { m_CellPos.m_lpCell->DeleteCreature(m_dwCID); m_CellPos.m_lpCell = NULL; } // äÆÃ ¼­¹ö·Î ·Î±×¾Æ¿ôÀ» ´øÁø´Ù. m_SerializeCharacterData.SendChatLogout(*this); // BG_TODO : µà¾óÀ̳ª, ´øÁ¯ÀÇ °æ¿ì¿¡´Â.. ´Ù½Ã ó¸®ÇØ¾ß ÇÒÁöµµ ¸ð¸¥´Ù. // VirtualArea ¿¡ ÀÖ¾ú´Ù¸é, VirtualArea ÀÇ Ä³¸¯Å͸®½ºÆ®¿¡¼­ Á¦°Å if (0 != GetMapIndex()) { VirtualArea::CVirtualAreaMgr::GetInstance().LeaveVirtualArea(this); } // ¼Òȯ¼ö°¡ ÀÖ´Ù¸é ¾ø¾Ø´Ù. if (NULL != m_lpSummonee) { m_lpSummonee->Dead(NULL); } // °Å·¡ÁßÀ̶ó¸é °Å·¡ Ãë¼Ò CCharacter* lpExchangeCharacter = m_Exchange.GetExchangeCharacter(); if (NULL != lpExchangeCharacter) { m_Exchange.ExchangeOK(false); CGameClientDispatch* lpExchangerDispatch = lpExchangeCharacter->GetDispatcher(); if (NULL != lpExchangerDispatch) { GameClientSendPacket::SendCharExchangeCmd(lpExchangerDispatch->GetSendStream(), m_dwCID, lpExchangeCharacter->GetCID(), PktExC::EXC_QUIT, PktExC::NO_SERVER_ERR); } } // µà¾ó ÃʱâÈ­ DuelInit(PktDuC::DUC_LOGOUT); // ÆÄƼã±â ¸®½ºÆ®¿¡¼­ »èÁ¦ CPartyMgr::GetInstance().DeleteFindPartyList(m_dwCID); // ÆÄƼ ÁÖ¹® Á¦°Å. if (0 != GetPID()) { // ÆÄƼ ·Î±×¾Æ¿ô if (NULL != m_pParty) { m_pParty->PrepareLogout(m_dwCID); } else { ERRLOG3(g_Log, "CID:0x%08x ÆÄƼ¿¡ ¼ÓÇÑ ³à¼®ÀÇ ÆÄƼ Æ÷ÀÎÅͰ¡ NULLÀÔ´Ï´Ù. PID:0x%08x, PartyPointer:0x%08x", m_dwCID, m_DBData.m_Info.PID, m_pParty); } } // ij¸¯ÅÍ¿¡ ÇöÁ¦ °É·ÁÀÖ´Â ½ºÆçµéÀ» DB¿¡ ÀúÀåÇÑ´Ù. // Á×Àº°Ô ¾Æ´Ï¸é ½ºÆçÀ» ´Ù½Ã ÀÐÁö ¾Ê´Â´Ù. // Á×ÀºÁ÷ÈÄ ½ºÆçÀ» ÀúÀåÇÑÈÄ ½ºÆçÀ» »èÁ¦Çϱ⠶§¹®¿¡ ¿©±â¼­ ´Ù½Ã ½ºÆçÀ» ÀúÀåÇϸé // ½ºÆçÀÌ »ç¶óÁø´Ù. if(!IsDead()) { const SPELL spell = GetSpellMgr().GetAffectedInfo().GetSpellInfo(); SetSpell(spell); } // ȯÀü¼Ò ±â´ÉÀ» »ç¿ëÇØ¼­ Àӽà °´Ã¼°¡ ³²¾ÆÀÖ´Ù¸é »èÁ¦ CRegularAgentDispatch::GetTempCharacterMgr().EraseChar(m_dwCID); GET_SINGLE_DISPATCH(lpDBAgentDispatch, CDBAgentDispatch, CDBAgentDispatch::GetDispatchTable()); if (0 != lpDBAgentDispatch) { CSendStream& AgentSendStream = lpDBAgentDispatch->GetSendStream(); // Äù½ºÆ® Á¤º¸ ÀúÀå GameClientSendPacket::SendCharQuestInfo(AgentSendStream, this); // ȯ°æ ¼³Á¤ Á¤º¸ ÀúÀå GameClientSendPacket::SendConfigInfoDB(AgentSendStream, this); } // º´±â¿¡ ž½ÂÁßÀ̶ó¸é ³»¸°°ÍÀ¸·Î °£ÁÖ if (IsRideArms()) { CSiegeObject* lpArms = CSiegeObjectMgr::GetInstance().GetSiegeObject(m_dwRideArmsCID); if (lpArms) { // ¼ö¼Û¼± Á¶Á¾»ç°¡ ³ª°£°æ¿ì if (Siege::RIDER_FOR_OWNER == lpArms->IsRider(m_dwCID)) { lpArms->AllGetOff(); } else { m_dwRideArmsCID = 0; lpArms->GetOff(m_dwCID); } } } int nTotalSize = sizeof(PktDBUpdate) + DBUpdateData::MAX_DBUPDATE_SIZE; char szCharBuffer[sizeof(PktDBUpdate) + DBUpdateData::MAX_DBUPDATE_SIZE]; char* lpCharacterInfo = szCharBuffer + sizeof(PktDBUpdate); PktDBUpdate* lpPktDBUpdate = reinterpret_cast(szCharBuffer); memset(lpPktDBUpdate, 0, sizeof(PktDBUpdate)); unsigned short usError = 0; unsigned char cAdmin = (true == IsAdmin()) ? 1 : 0; bool bCharacterUpdate = GetCharacterInfo(lpCharacterInfo, &nTotalSize, lpPktDBUpdate->m_usUpdate); if (!bCharacterUpdate) { nTotalSize = 0; usError = 1; std::fill_n(lpPktDBUpdate->m_usUpdate, unsigned short(DBUpdateData::MAX_UPDATE_DB), 0); ERRLOG1(g_Log, "CID:0x%08x µ¥ÀÌÅ͸¦ º¹»çÇØ ¿Ã ¼ö ¾ø½À´Ï´Ù. DB¿¡ ¾÷µ¥ÀÌÆ® ÇÒ ¼ö ¾ø½À´Ï´Ù.", m_dwCID); } else if (0 != lpDBAgentDispatch) { if (IsOperationFlagSet(CHAR_INFO_LOADED)) { CSendStream& AgentSendStream = lpDBAgentDispatch->GetSendStream(); // â°í µ¥ÀÌÅÍ ¾÷µ¥ÀÌÆ®(â°í°¡ ¿­·Á ÀÖÀ¸¸é ¾÷µ¥ÀÌÆ®ÇÑ´Ù.) // ¼ø¼­ ÁÖÀÇ! DB¿¡ UpdateÇÒ ¶§´Â â°í ¾÷µ¥ÀÌÆ® ÈÄ, ij¸¯Å͸¦ ¾÷µ¥ÀÌÆ®ÇÑ´Ù. if (!m_Deposit.DBUpdate(AgentSendStream)) { ERRLOG1(g_Log, "CID:0x%08x â°í ¾÷µ¥ÀÌÆ® ½ÇÆÐ", m_dwCID); } // ·Î±×¾Æ¿ô Á¤º¸ DBAgent¿¡ º¸³»±â lpPktDBUpdate->m_dlItemSerial = Item::CItemFactory::GetInstance().GetItemUID(); lpPktDBUpdate->m_dwSessionID = m_dwSessionID; lpPktDBUpdate->m_dwUserID = m_dwUID; lpPktDBUpdate->m_dwCharID = m_dwCID; lpPktDBUpdate->m_TypeCode = eUpdateType; lpPktDBUpdate->m_dwRequestKey = 0; lpPktDBUpdate->m_cAdminFlag = GetGMModelFlag(); lpPktDBUpdate->m_dwRequestKey = 0; lpPktDBUpdate->m_Address.S_un.S_addr = 0; lpPktDBUpdate->m_cAdminLevel = 0; // WORK_LIST 2.4 °èÁ¤ ±¹ÀûÀ» °ÔÀÓ¼­¹öÀÇ Ä³¸¯ÅͰ¡ °¡Áöµµ·Ï ±¸Çö //lpPktDBUpdate->m_cPadding = 0; lpPktDBUpdate->m_cAccountNation = 0; lpPktDBUpdate->m_cNameChangeCount = 0; lpPktDBUpdate->m_cGuildWarFlag = 0; lpPktDBUpdate->m_cRealmWarFlag = 0; lpPktDBUpdate->m_cRealmPoint = 0; lpPktDBUpdate->m_cTacticsFlag = 0; lpPktDBUpdate->m_PlayTime = 0; lpPktDBUpdate->m_PremiumTime = 0; lpPktDBUpdate->m_PremiumType = 0; if (AgentSendStream.WrapCompress(reinterpret_cast(lpPktDBUpdate), static_cast(sizeof(PktDBUpdate) + nTotalSize), CmdDBUpdateData, 0, 0)) { LOG_INOUT( char szExp[64]; Math::Convert::Hex64ToStr(szExp, m_DBData.m_Info.Exp); DETLOG7(g_Log, "UID:%d/CID:0x%08x(0x%p)/DispatchPointer:0x%p ÀÇ Ä³¸¯ÅÍ Á¤º¸¸¦ DBAgent¿¡ ¾÷µ¥ÀÌÆ®ÇÕ´Ï´Ù. À¯Àú ·Î±×¾Æ¿ôÀ» ó¸®ÇÕ´Ï´Ù." " ·Î±×¾Æ¿ô¿¡ ¼º°øÇÏ¿´½À´Ï´Ù. ¸î°¡Áö ±âº» Á¤º¸¸¦ Âï½À´Ï´Ù. %s(lev:%2d, exp:%s)", m_dwUID, m_dwCID, this, m_lpGameClientDispatch, m_DBData.m_Info.Name, m_DBData.m_Info.Level, szExp) ); } else { ERRLOG1(g_Log, "CID:0x%08x DB¿¡ ij¸¯ÅÍ ¾÷µ¥ÀÌÆ®¸¦ ÇÒ ¼ö ¾ø½À´Ï´Ù. Àü¼Û¿¡ ½ÇÆÐÇß½À´Ï´Ù.", m_dwCID); } } else { // µ¥ÀÌÅͰ¡ ¼¼ÆÃµÇÁö ¾Ê¾ÒÀ¸´Ï, Á¤»ó ·Î±×¾Æ¿ôÀº ¾Æ´Ï´Ù. DBAgentPacketParse::SendAbnormalLogout( m_dwUID, m_dwCID, m_dwSessionID, 0, m_lpGameClientDispatch); } } else { ERRLOG2(g_Log, "CID:0x%08x/AgentSession:0x%p/ DBUpdate failed.", m_dwCID, lpDBAgentDispatch); } SOCKADDR_IN remoteAddr; if (0 != m_lpGameClientDispatch) { remoteAddr = m_lpGameClientDispatch->GetRemoteAddr().get_addr_in(); } else { memset(&remoteAddr, 0, sizeof(SOCKADDR_IN)); } // °ÔÀӷα׿¡ ij¸¯ÅÍ ·Î±×¾Æ¿ô ³²±â±â GAMELOG::LogCharLoginOut(m_dwUID, this, &remoteAddr, lpCharacterInfo, nTotalSize, lpPktDBUpdate->m_usUpdate, GAMELOG::CMD::CHAR_LOGOUT, usError); // ·Î±× ¼­¹ö¿¡ ·Î±×¾Æ¿ô º¸³»±â. // SendLogPacket::CharLogout(*this); LOG_INOUT(DETLOG4(g_Log, "UID:%d/CID:0x%08x(0x%p)/DispatchPointer:0x%p ´ÙÀ½ À¯ÀúÀÇ ·Î±×¾Æ¿ôÀ» ó¸®ÇÕ´Ï´Ù. ´ÙÀ½ À¯Àú¸¦ Á¦°ÅÇÕ´Ï´Ù.", m_dwUID, m_dwCID, this, m_lpGameClientDispatch)); return CCreatureManager::GetInstance().DeleteCreature(m_dwCID); } void CheckDuplicatedItem(CCharacter& character) { using namespace Item; CItemOwnerInfo itemOwnerInfo( character.GetCharacterName(), character.GetUID(), character.GetCID()); CItemOwnerInfo* lpDuplicateOwner = 0; CItemFactory& itemFactory = Item::CItemFactory::GetInstance(); // first : ¼ÒÀ¯ÀÚ Á¤º¸ / second : º¹»ç ¾ÆÀÌÅÛ Qty typedef std::pair DuplicateInfo; typedef std::multimap, boost::fast_pool_allocator > > DuplicatedMap; DuplicatedMap duplicatedItemMap; // º¹»ç µ¥ÀÌÅͰ¡ ÀÖÀ¸¸é DBÁß°è·Î ¼Û½ÅÇϱâ À§Çؼ­.. GET_SINGLE_DISPATCH(lpDBAgentDispatch, CDBAgentDispatch, CDBAgentDispatch::GetDispatchTable()); // ¾ÆÀÌÅÛ ÄÁÅ×À̳ʵéÀ» ¹è¿­¿¡ ³Ö´Â´Ù. const int MAX_CONTAINER_SET = 7; CItemContainer* containerSet[MAX_CONTAINER_SET] = { &character.GetInventory(), &character.GetEquipments(), &character.GetExtra(), &character.GetExchange(), &character.GetDeposit(), &character.GetStall(), &character.GetTempInven(), }; CItemContainer** lppContainerPos = containerSet; CItemContainer** lppContainerEnd = containerSet + MAX_CONTAINER_SET; for(; lppContainerPos != lppContainerEnd; ++lppContainerPos) { CItemContainer& itemContainer = **lppContainerPos; CItemContainer::iterator pos = itemContainer.begin(); CItemContainer::iterator end = itemContainer.end(); for(; pos != end; ++pos) { CItem* lpItem = *pos; if (0 != lpItem) { unsigned __int64 dwItemSerial = lpItem->GetUID(); lpDuplicateOwner = itemFactory.AddItemMap(dwItemSerial, itemOwnerInfo); if (0 != lpDuplicateOwner) { // º¹»ç ¹ß°ß. ÀÏ´Ü ³ª¿Í À̳༮ÀÇ ½Ã¸®¾ó ¹× Á¤º¸¸¦ ¸®½ºÆ® µîÀ¸·Î ±â¾ïÇØµÎ¾ú´Ù°¡ // °³¼ö¸¦ ¼¼¾î¼­ ³ªÁß¿¡ Çѹø¿¡ º¸³½´Ù. // ³» ¾ÆÀÌÅÛ Á¤º¸ : dwItemSerial, itemOwnerInfo // »ó´ë ¾ÆÀÌÅÛ Á¤º¸ : dwItemSerial, lpDuplicateOwner std::pair result = duplicatedItemMap.equal_range(dwItemSerial); bool bAddedQty = false; bool bAddedDuplicateOwner = false; for(;result.first != result.second; ++result.first) { unsigned __int64 dwItemUID = result.first->first; // first : ¼ÒÀ¯ÀÚ Á¤º¸ / second : º¹»ç ¾ÆÀÌÅÛ Qty DuplicateInfo& duplicateInfo = result.first->second; CItemOwnerInfo& duplicateOwnerInfo = *duplicateInfo.first; if (duplicateOwnerInfo.GetCID() == itemOwnerInfo.GetCID()) { // ¼ÒÀ¯ÀÚ°¡ °°Àº ¾ÆÀÌÅÛÀÌ´Ù. Qty¸¦ Áõ°¡½ÃÄÑÁØ´Ù. // Qty´Â º¹Á¦µÈ ¾ÆÀÌÅÛÀ» '³»°¡' ¸î°³³ª °¡Áö°í ÀÖ´ÂÁö¸¦ ³ªÅ¸³½´Ù. ++duplicateInfo.second; bAddedQty = true; } else if (duplicateOwnerInfo.GetCID() == lpDuplicateOwner->GetCID()) { // ÀÌÀü¿¡ °¡Áö°í ÀÖ´ø »ç¶÷ÀÌ ³»°¡ ¾Æ´Ï¶ó ´Ù¸¥ »ç¶÷ÀÌ´Ù. bAddedDuplicateOwner = true; } } if (!bAddedQty) { // ¼ýÀÚ°¡ Ãß°¡µÇÁö ¾Ê¾ÒÀ¸¸é, Ç׸ñ¿¡ »õ·Î Ãß°¡. duplicatedItemMap.insert(result.second, DuplicatedMap::value_type(dwItemSerial, DuplicateInfo(&itemOwnerInfo, (itemOwnerInfo.GetCID() == lpDuplicateOwner->GetCID()) ? 2 : 1))); } if (!bAddedDuplicateOwner && lpDuplicateOwner->GetCID() != itemOwnerInfo.GetCID()) { duplicatedItemMap.insert(result.second, DuplicatedMap::value_type(dwItemSerial, DuplicateInfo(lpDuplicateOwner, 1))); } } } } } DuplicatedMap::iterator pos = duplicatedItemMap.begin(); DuplicatedMap::iterator end = duplicatedItemMap.end(); if (0 != lpDBAgentDispatch) { // Àü¼Û for(; pos != end; ++pos) { SendItemDuplicatedLog(lpDBAgentDispatch->GetSendStream(), pos->first, *pos->second.first, pos->second.second); } } else { // ·Î±×¸¦ ³²±ä´Ù. for(; pos != end; ++pos) { DuplicateInfo& dupInfo = pos->second; ERRLOG5(g_Log, "UID:%10u / CID:%10u / CharName:%s / ItemSerial:0x%I64X / Qty:%u / ¾ÆÀÌÅÛ º¹»ç°¡ ¹ß°ßµÇ¾ú½À´Ï´Ù", dupInfo.first->GetUID(), dupInfo.first->GetCID(), dupInfo.first->GetName(), pos->first, dupInfo.second); } } } void SendItemDuplicatedLog(CSendStream& SendStream, unsigned __int64 dwItemSerial, Item::CItemOwnerInfo& itemOwnerInfo, unsigned long dwItemQty) { PktItemDuplicated* lpPktItemDuplicated = reinterpret_cast(SendStream.GetBuffer(sizeof(PktItemDuplicated))); if (0 != lpPktItemDuplicated) { lpPktItemDuplicated->m_cLogCmd = PktServerLog::ITEM_DUPLICATED_LOG; strncpy(lpPktItemDuplicated->m_szName, itemOwnerInfo.GetName(), PktItemDuplicated::MAX_NAME - 1); lpPktItemDuplicated->m_szName[PktItemDuplicated::MAX_NAME - 1] = 0; lpPktItemDuplicated->m_dwItemSerial = dwItemSerial; lpPktItemDuplicated->m_dwUID = itemOwnerInfo.GetUID(); lpPktItemDuplicated->m_dwCID = itemOwnerInfo.GetCID(); lpPktItemDuplicated->m_dwQty = dwItemQty; SendStream.WrapHeader(sizeof(PktItemDuplicated), CmdServerLog, 0, 0); } } void RealmSkill::RealmInchantAdd(CCharacter* lpCharacter) { // edith 2010.01.02 °øÇå ÈÆÀåÀÇ °³³äÀÌ ¹Ù²î¸é¼­ °øÇåÈÆÀå ¹öÇÁ¸¦ Á¦¿ÜÇÑ´Ù. return; // edith 2008.05.28 °øÇå ÈÆÀ庰 ¹öÇÁ ¼³Á¤ // °øÇå ÈÆÀå Æ÷ÀÎÆ® ¼¼ÆÃ // unsigned char cLevel[2][6] = { 0, 1, 1, 2, 2, 3, 0, 0, 1, 1, 2, 2 }; if(!lpCharacter) { return; } unsigned char cPoint = lpCharacter->GetRealmPoint(); if(!cPoint) { return; } // HP È¿°ú. if(cLevel[0][cPoint]) { Skill::CAddSpell(CSpell::Spell_Info(Skill::CProcessTable::ProcessInfo::m_NullProtoType, lpCharacter, Skill::SpellType::REALM_SPELL, Skill::SpellID::RealmHP, cLevel[0][cPoint], CSpell::INFINITE_DURATION))(lpCharacter); } // MP È¿°ú. if(cLevel[1][cPoint]) { Skill::CAddSpell(CSpell::Spell_Info(Skill::CProcessTable::ProcessInfo::m_NullProtoType, lpCharacter, Skill::SpellType::REALM_SPELL, Skill::SpellID::RealmMP, cLevel[1][cPoint], CSpell::INFINITE_DURATION))(lpCharacter); } } void RealmSkill::RealmInchantRemove(CCharacter* lpCharacter) { if(!lpCharacter) return; // HP È¿°ú. if(lpCharacter->GetSpellMgr().GetAffectedInfo().GetSpell(Skill::SpellID::RealmHP)) { lpCharacter->GetSpellMgr().GetAffectedInfo().RemoveEnchantBySpellType(Skill::SpellID::RealmHP); } // MP È¿°ú. if(lpCharacter->GetSpellMgr().GetAffectedInfo().GetSpell(Skill::SpellID::RealmMP)) { lpCharacter->GetSpellMgr().GetAffectedInfo().RemoveEnchantBySpellType(Skill::SpellID::RealmMP); } }