bool GuildUnion::removeGuild(GuildID_t gID ) throw(Error) { if (m_MasterGuildID == gID ) return false; list<GuildID_t>::iterator itr = findGuildItr(gID); if (itr == m_Guilds.end() ) return false; m_Guilds.erase(itr); Statement* pStmt = NULL; BEGIN_DB { pStmt = g_pDatabaseManager->getConnection("DARKEDEN")->createStatement(); pStmt->executeQuery("DELETE FROM GuildUnionMember WHERE UnionID = %u and OwnerGuildID = %u", m_UnionID, gID); if (pStmt->getAffectedRowCount() < 1 ) { filelog("GuildUnion.log", "[%u:%u] 탈퇴하려는데 해당 레코드가 없습니다.", m_UnionID, gID); } SAFE_DELETE(pStmt); } END_DB(pStmt); return true; }
//---------------------------------------------------------------------- // init //---------------------------------------------------------------------- void UniqueItemManager::init() throw(Error) { __BEGIN_TRY __BEGIN_DEBUG Statement* pStmt = NULL; BEGIN_DB { pStmt = g_pDatabaseManager->getConnection("DARKEDEN")->createStatement(); // DB에서 현재의 값을 읽어온다. Result* pResult = pStmt->executeQuery( "SELECT ItemClass, ItemType FROM UniqueItemInfo"); // 지정된 itemClas, itemType을 Unique Item으로 설정한다. while (pResult->next()) { Item::ItemClass itemClass = (Item::ItemClass)pResult->getInt(1); int itemType = pResult->getInt(2); ItemInfo* pItemInfo = g_pItemInfoManager->getItemInfo(itemClass, itemType); Assert(pItemInfo!=NULL); pItemInfo->setUnique(); } SAFE_DELETE(pStmt); } END_DB(pStmt); __END_CATCH __END_DEBUG }
void GuildUnion::create() throw(Error) { __BEGIN_TRY Statement* pStmt = NULL; BEGIN_DB { pStmt = g_pDatabaseManager->getConnection("DARKEDEN")->createStatement(); pStmt->executeQuery("INSERT INTO GuildUnionInfo (MasterGuildID) VALUES (%u)", m_MasterGuildID); m_UnionID = pStmt->getInsertID(); list<GuildID_t>::iterator itr = m_Guilds.begin(); for (; itr != m_Guilds.end() ; ++itr ) { pStmt->executeQuery("INSERT INTO GuildUnionMember (UnionID, OwnerGuildID) VALUES (%u, %u)", m_UnionID, (*itr)); } SAFE_DELETE(pStmt); } END_DB(pStmt); __END_CATCH }
//---------------------------------------------------------------------- // is Possible Create //---------------------------------------------------------------------- bool UniqueItemManager::isPossibleCreate(Item::ItemClass itemClass, ItemType_t itemType) throw(Error) { __BEGIN_TRY __BEGIN_DEBUG Statement* pStmt = NULL; BEGIN_DB { pStmt = g_pDatabaseManager->getConnection("DARKEDEN")->createStatement(); // DB에서 현재의 값을 읽어온다. Result* pResult = pStmt->executeQuery( "SELECT LimitNumber, CurrentNumber FROM UniqueItemInfo WHERE ItemClass=%d AND ItemType=%d", (int)itemClass, (int)itemType); if (pResult->next()) { int limitNumber = pResult->getInt(1); int currentNumber = pResult->getInt(2); return limitNumber==0 || currentNumber<limitNumber; } SAFE_DELETE(pStmt); } END_DB(pStmt); __END_CATCH __END_DEBUG return false; }
//---------------------------------------------------------------------- // // GSModifyGuildMemberHandler::execute() // //---------------------------------------------------------------------- void GSModifyGuildMemberHandler::execute (GSModifyGuildMember* pPacket, Player* pPlayer ) throw(ProtocolException , Error ) { __BEGIN_TRY __BEGIN_DEBUG_EX #ifdef __SHARED_SERVER__ //cout << "GSModifyGuildMember received" << endl; Assert(pPacket != NULL); // 길드를 가져온다. Guild* pGuild = g_pGuildManager->getGuild(pPacket->getGuildID()); //try { Assert(pGuild != NULL); } catch (Throwable& ) { return; } if (pGuild==NULL) return; // 길드의 멤버인지 확인한다. GuildMember* pGuildMember = pGuild->getMember(pPacket->getName()); //try { Assert(pGuildMember != NULL); } catch (Throwable& ) { return; } if (pGuildMember==NULL) return; // 보낸사람이 길드 마스터인지 확인한다. (길드 마스터를 바꿀때는 예외 ) if (pGuild->getMaster() != pPacket->getSender() && pPacket->getGuildMemberRank() != GuildMember::GUILDMEMBER_RANK_MASTER ) return; if (pGuildMember->getRank() == GuildMember::GUILDMEMBER_RANK_WAIT && pPacket->getGuildMemberRank() == GuildMember::GUILDMEMBER_RANK_NORMAL ) { /////////////////////////////////////////////////////////////////////////////////////// // 길드 멤버 가입을 승인한 경우, DB에 Slayer, Vampire, Ousters 테이블의 GuildID 를 바꾼다. /////////////////////////////////////////////////////////////////////////////////////// Statement* pStmt = NULL; BEGIN_DB { pStmt = g_pDatabaseManager->getConnection("DARKEDEN" )->createStatement(); if (pGuild->getRace() == Guild::GUILD_RACE_SLAYER ) { pStmt->executeQuery("UPDATE Slayer SET GuildID = %d WHERE Name = '%s'", pGuild->getID(), pGuildMember->getName().c_str()); pStmt->executeQuery("INSERT INTO Messages (Receiver, Message ) VALUES ('%s', '%s' )", pGuildMember->getName().c_str(), g_pStringPool->c_str(STRID_TEAM_JOIN_ACCEPT )); } else if (pGuild->getRace() == Guild::GUILD_RACE_VAMPIRE ) { pStmt->executeQuery("UPDATE Vampire SET GuildID = %d WHERE Name = '%s'", pGuild->getID(), pGuildMember->getName().c_str()); pStmt->executeQuery("INSERT INTO Messages (Receiver, Message ) VALUES ('%s', '%s' )", pGuildMember->getName().c_str(), g_pStringPool->c_str(STRID_CLAN_JOIN_ACCEPT )); } else if (pGuild->getRace() == Guild::GUILD_RACE_OUSTERS ) { pStmt->executeQuery("UPDATE Ousters SET GuildID = %d WHERE Name = '%s'", pGuild->getID(), pGuildMember->getName().c_str()); pStmt->executeQuery("INSERT INTO Messages (Receiver, Message ) VALUES ('%s', '%s' )", pGuildMember->getName().c_str(), g_pStringPool->c_str(STRID_CLAN_JOIN_ACCEPT )); } SAFE_DELETE(pStmt); } END_DB(pStmt) // Guild Member 정보를 변경한다. pGuild->modifyMemberRank(pGuildMember->getName(), pPacket->getGuildMemberRank()); }
//---------------------------------------------------------------------- // load data from database //---------------------------------------------------------------------- void UserInfoManager::load () throw(Error ) { __BEGIN_TRY Statement * pStmt; BEGIN_DB { pStmt = g_pDatabaseManager->getConnection("DARKEDEN")->createStatement(); Result* pResult = pStmt->executeQuery( "SELECT MAX(WorldID) FROM GameServerGroupInfo" ); if (pResult->getRowCount() == 0) { throw Error("GameServerGroupInfo TABLE does not exist!"); } pResult->next(); m_MaxWorldID = pResult->getInt(1) + 2; SAFE_DELETE(pStmt); } END_DB(pStmt) m_UserInfos= new HashMapUserInfo[m_MaxWorldID]; try { pStmt = g_pDatabaseManager->getConnection("DARKEDEN")->createStatement(); Result * pResult = pStmt->executeQuery( "SELECT WorldID, GroupID FROM GameServerGroupInfo" ); while (pResult->next() ) { UserInfo * pUserInfo = new UserInfo(); WorldID_t WorldID = pResult->getInt(1); pUserInfo->setWorldID(WorldID); pUserInfo->setServerGroupID(pResult->getInt(2)); pUserInfo->setUserNum(0); addUserInfo(pUserInfo); } } catch (SQLQueryException & sqe ) { // 필살 삭제! delete pStmt; throw Error(sqe.toString()); } // 필살 삭제! delete pStmt; __END_CATCH }
void GQuestStatus::save() throw(Error) { __BEGIN_TRY Statement* pStmt = NULL; BEGIN_DB { pStmt = g_pDatabaseManager->getConnection("DARKEDEN")->createStatement(); pStmt->executeQuery("REPLACE INTO GQuestSave (QuestID, OwnerID, Time, Status) VALUES (%u, '%s', now(), %u)", m_QuestID, m_pOwner->getName().c_str(), m_Status); SAFE_DELETE(pStmt); } END_DB(pStmt); __END_CATCH }
void GuildUnion::destroy() throw(Error) { __BEGIN_TRY Statement* pStmt = NULL; BEGIN_DB { pStmt = g_pDatabaseManager->getConnection("DARKEDEN")->createStatement(); pStmt->executeQuery("DELETE FROM GuildUnionInfo WHERE UnionID = %u", m_UnionID); pStmt->executeQuery("DELETE FROM GuildUnionMember WHERE UnionID = %u", m_UnionID); } END_DB(pStmt); __END_CATCH }
void CastleShrineInfoManager::load() throw(Error) { __BEGIN_TRY cout << "[GAMESERVER] Loading Shrines..." << endl; Statement* pStmt = NULL; Result* pResult = NULL; BEGIN_DB { pStmt = g_pDatabaseManager->getConnection("DARKEDEN")->createStatement(); pResult = pStmt->executeQuery("SELECT ID, Name, ItemType, GuardZoneID, GuardX, GuardY, GuardMType, HolyZoneID, HolyX, HolyY, HolyMType FROM CastleShrineInfo"); while (pResult->next() ) { int i = 0; CastleShrineSet* pShrineSet = new CastleShrineSet(); pShrineSet->m_ShrineID = pResult->getInt(++i); pShrineSet->m_GuardShrine.setName(pResult->getString(++i )); pShrineSet->m_HolyShrine.setName(pShrineSet->m_GuardShrine.getName()); pShrineSet->m_ItemType = pResult->getInt(++i); pShrineSet->m_GuardShrine.setZoneID(pResult->getInt(++i )); pShrineSet->m_GuardShrine.setX(pResult->getInt(++i )); pShrineSet->m_GuardShrine.setY(pResult->getInt(++i )); pShrineSet->m_GuardShrine.setMonsterType(pResult->getInt(++i )); pShrineSet->m_HolyShrine.setZoneID(pResult->getInt(++i )); pShrineSet->m_HolyShrine.setX(pResult->getInt(++i )); pShrineSet->m_HolyShrine.setY(pResult->getInt(++i )); pShrineSet->m_HolyShrine.setMonsterType(pResult->getInt(++i )); pShrineSet->m_GuardShrine.setShrineType(ShrineInfo::SHRINE_GUARD); pShrineSet->m_HolyShrine.setShrineType(ShrineInfo::SHRINE_HOLY); // ItemType과 Shrine ID는 같아야 한다. 같지 않을 경우 DB설정 오류로 로딩과정에서 막는다. if (pShrineSet->m_ItemType != pShrineSet->m_ShrineID ) Assert(false); addShrineSet(pShrineSet); } } END_DB(pStmt ) cout << "[GAMESERVER] Shrines Loaded." << endl; __END_CATCH }
bool GuildUnion::addGuild(GuildID_t gID ) throw(Error) { if (hasGuild(gID ) ) return false; m_Guilds.push_back(gID); Statement* pStmt = NULL; BEGIN_DB { pStmt = g_pDatabaseManager->getConnection("DARKEDEN")->createStatement(); pStmt->executeQuery("INSERT INTO GuildUnionMember (UnionID, OwnerGuildID) VALUES (%u, %u)", m_UnionID, gID); SAFE_DELETE(pStmt); } END_DB(pStmt); return true; }
void GameServerGroupInfoManager::load() throw(Error) { __BEGIN_TRY Statement * pStmt; BEGIN_DB { pStmt = g_pDatabaseManager->getConnection("DARKEDEN")->createStatement(); Result* pResult = pStmt->executeQuery("SELECT MAX(`WorldID`) FROM `GameServerGroupInfo`"); if (pResult->getRowCount() == 0) throw Error("[GameServerGroupInfoManager] GameServerGroupInfo TABLE does not exist!"); pResult->next(); m_MaxWorldID = pResult->getInt(1) + 2; SAFE_DELETE(pStmt); } END_DB(pStmt) m_GameServerGroupInfos = new HashMapGameServerGroupInfo[m_MaxWorldID]; try { pStmt = g_pDatabaseManager->getConnection("DARKEDEN")->createStatement(); Result * pResult = pStmt->executeQuery("SELECT `WorldID`, `GroupID`, `GroupName` FROM `GameServerGroupInfo`"); while(pResult->next()) { GameServerGroupInfo * pGameServerGroupInfo = new GameServerGroupInfo(); WorldID_t WorldID = pResult->getInt(1); pGameServerGroupInfo->setWorldID(WorldID); pGameServerGroupInfo->setGroupID(pResult->getInt(2)); pGameServerGroupInfo->setGroupName(pResult->getString(3)); addGameServerGroupInfo(pGameServerGroupInfo, WorldID); } delete pStmt; } catch (SQLQueryException & sqe) { delete pStmt; throw Error(sqe.toString()); } catch (Throwable & t) { cout << t.toString() << endl; } __END_CATCH }
int SMSAddressBook::removeAddressElement(DWORD eID ) { map<DWORD, SMSAddressElement*>::iterator itr = m_Addresses.find(eID); if (itr == m_Addresses.end() ) return GCAddressListVerify::DELETE_FAIL_NO_SUCH_EID; m_Addresses.erase(itr); Statement* pStmt = NULL; BEGIN_DB { pStmt = g_pDatabaseManager->getConnection("DARKEDEN")->createStatement(); pStmt->executeQuery("DELETE FROM SMSAddressBook WHERE eID = %u AND OwnerID = '%s'", eID, m_pOwner->getName().c_str()); SAFE_DELETE(pStmt); } END_DB(pStmt); return 0; }
int SMSAddressBook::addAddressElement(SMSAddressElement* pElement ) { if (m_Addresses.size() > MAX_ADDRESS_NUM ) return GCAddressListVerify::ADD_FAIL_MAX_NUM_EXCEEDED; if (m_Addresses[pElement->getID()] != NULL ) return GCAddressListVerify::ADD_FAIL_INVALID_DATA; m_Addresses[pElement->getID()] = pElement; Statement* pStmt = NULL; BEGIN_DB { pStmt = g_pDatabaseManager->getConnection("DARKEDEN")->createStatement(); pStmt->executeQuery("INSERT INTO SMSAddressBook (eID, OwnerID, CharacterName, CustomName, Number) VALUES (%u, '%s', '%s', '%s', '%s')", pElement->m_ElementID, m_pOwner->getName().c_str(), pElement->m_CharacterName.c_str(), pElement->m_CustomName.c_str(), pElement->m_Number.c_str()); SAFE_DELETE(pStmt); } END_DB(pStmt); return 0; }
void SMSAddressBook::load() throw(Error) { __BEGIN_TRY m_Addresses.clear(); Assert(m_pOwner != NULL); m_NextEID = 1; Statement* pStmt = NULL; BEGIN_DB { pStmt = g_pDatabaseManager->getConnection("DARKEDEN")->createStatement(); Result* pResult = pStmt->executeQuery("SELECT eID, CharacterName, CustomName, Number FROM SMSAddressBook WHERE OwnerID='%s'", m_pOwner->getName().c_str()); while (pResult->next() ) { SMSAddressElement* pElement = new SMSAddressElement( pResult->getInt(1), pResult->getString(2), pResult->getString(3), pResult->getString(4)); // Assert(addAddressElement(pElement )); Assert(m_Addresses[pElement->getID()] == NULL); m_Addresses[pElement->getID()] = pElement; if (m_NextEID <= pElement->getID() ) m_NextEID = pElement->getID()+1; } SAFE_DELETE(pStmt); } END_DB(pStmt); __END_CATCH }
//---------------------------------------------------------------------- // createItem //---------------------------------------------------------------------- // DB에서 개수 증가 //---------------------------------------------------------------------- void UniqueItemManager::createItem(Item::ItemClass itemClass, ItemType_t itemType) throw(Error) { __BEGIN_TRY __BEGIN_DEBUG Statement* pStmt = NULL; BEGIN_DB { pStmt = g_pDatabaseManager->getConnection("DARKEDEN")->createStatement(); // DB에서 현재의 값을 읽어온다. pStmt->executeQuery( "UPDATE UniqueItemInfo SET CurrentNumber=CurrentNumber+1 WHERE ItemClass=%d AND ItemType=%d", (int)itemClass, (int)itemType); SAFE_DELETE(pStmt); } END_DB(pStmt); __END_CATCH __END_DEBUG }
//---------------------------------------------------------------------- // // GSExpelGuildMemberHandler::execute() // //---------------------------------------------------------------------- void GSExpelGuildMemberHandler::execute (GSExpelGuildMember* pPacket, Player* pPlayer ) throw(ProtocolException , Error ) { __BEGIN_TRY __BEGIN_DEBUG_EX #ifdef __SHARED_SERVER__ //cout << "GSExpelGuildMember received" << endl; Assert(pPacket != NULL); // 플레이어가 속한 길드를 가져온다. Guild* pGuild = g_pGuildManager->getGuild(pPacket->getGuildID()); //try { Assert(pGuild != NULL); } catch (Throwable& ) { return; } if (pGuild==NULL) return; // 플레이어가 길드의 멤버인지 확인한다. GuildMember* pGuildMember = pGuild->getMember(pPacket->getName()); //try { Assert(pGuildMember != NULL); } catch (Throwable& ) { return; } if (pGuildMember==NULL) return; // 길드 탈퇴 로그를 남긴다. filelog("GuildExit.log", "GuildID: %d, GuildName: %s, Expel: %s, By: %s", pGuild->getID(), pGuild->getName().c_str(), pPacket->getName().c_str(), pPacket->getSender().c_str()); /////////////////////////////////////////////////////////////////// // DB에 Slayer, Vampire, Ousters 테이블의 GuildID 를 바꾼다. /////////////////////////////////////////////////////////////////// Statement* pStmt = NULL; BEGIN_DB { pStmt = g_pDatabaseManager->getConnection("DARKEDEN" )->createStatement(); if (pGuild->getRace() == Guild::GUILD_RACE_SLAYER ) { pStmt->executeQuery("UPDATE Slayer SET GuildID = 99 WHERE Name = '%s'", pGuildMember->getName().c_str()); } else if (pGuild->getRace() == Guild::GUILD_RACE_VAMPIRE ) { pStmt->executeQuery("UPDATE Vampire SET GuildID = 0 WHERE Name = '%s'", pGuildMember->getName().c_str()); } else if (pGuild->getRace() == Guild::GUILD_RACE_OUSTERS ) { pStmt->executeQuery("UPDATE Ousters SET GuildID = 66 WHERE Name = '%s'", pGuildMember->getName().c_str()); } SAFE_DELETE(pStmt); } END_DB(pStmt) // Guild Member 를 expire 시킨다. pGuildMember->expire(); // Guild 에서 삭제한다. pGuild->deleteMember(pGuildMember->getName()); // 게임 서버로 보낼 패킷을 만든다. SGExpelGuildMemberOK sgExpelGuildMemberOK; sgExpelGuildMemberOK.setGuildID(pGuild->getID()); sgExpelGuildMemberOK.setName(pPacket->getName()); sgExpelGuildMemberOK.setSender(pPacket->getSender()); // 게임 서버로 패킷을 보낸다. g_pGameServerManager->broadcast(&sgExpelGuildMemberOK); // 길드 인원이 5명 미만이 될 경우 길드를 삭제한다. if (pGuild->getState() == Guild::GUILD_STATE_ACTIVE && pGuild->getActiveMemberCount() < MIN_GUILDMEMBER_COUNT ) { // 길드 삭제 로그를 남긴다. filelog("GuildBroken.log", "GuildID: %d, GuildName: %s, MemberCount: %d, Expel: %s", pGuild->getID(), pGuild->getName().c_str(), pGuild->getActiveMemberCount(), pPacket->getName().c_str()); // 길드 멤버 expire and delete HashMapGuildMember& Members = pGuild->getMembers(); HashMapGuildMemberItor itr = Members.begin(); BEGIN_DB { pStmt = g_pDatabaseManager->getConnection("DARKEDEN" )->createStatement(); for (; itr != Members.end(); itr++ ) { GuildMember* pGuildMember = itr->second; /////////////////////////////////////////////////////////////////// // DB에 Slayer, Vampire, Ousters 테이블의 GuildID 를 바꾼다. /////////////////////////////////////////////////////////////////// if (pGuild->getRace() == Guild::GUILD_RACE_SLAYER ) { pStmt->executeQuery("UPDATE Slayer SET GuildID = 99 WHERE Name = '%s'", pGuildMember->getName().c_str()); } else if (pGuild->getRace() == Guild::GUILD_RACE_VAMPIRE ) { pStmt->executeQuery("UPDATE Vampire SET GuildID = 0 WHERE Name = '%s'", pGuildMember->getName().c_str()); } else if (pGuild->getRace() == Guild::GUILD_RACE_OUSTERS ) { pStmt->executeQuery("UPDATE Ousters SET GuildID = 66 WHERE Name = '%s'", pGuildMember->getName().c_str()); } // 길드 멤버를 expire 시킨다. pGuildMember->expire(); // 완전히 DB에서 제거한다. //pGuildMember->destroy(); // 길드 멤버를 삭제 SAFE_DELETE(pGuildMember); } SAFE_DELETE(pStmt); } END_DB(pStmt) Members.clear(); // 길드를 삭제한다 pGuild->setState(Guild::GUILD_STATE_BROKEN); pGuild->save(); SAFE_DELETE(pGuild); g_pGuildManager->deleteGuild(pPacket->getGuildID()); // 길드를 삭제하도록 패킷을 보낸다. SGDeleteGuildOK sgDeleteGuildOK; sgDeleteGuildOK.setGuildID(pPacket->getGuildID()); g_pGameServerManager->broadcast(&sgDeleteGuildOK); }
//-------------------------------------------------------------------------------- // // load data from database // // 데이타베이스에 연결해서 ZoneGroup 을 로드해온다. // //-------------------------------------------------------------------------------- void ZoneGroupManager::load () throw(Error) { __BEGIN_TRY __BEGIN_DEBUG cout << "[ZoneGroupManager] Loading..." << endl; Statement* pStmt = NULL; list<ZoneGroupID_t> ZoneGroupIDList; // 먼저 존 그룹 아이디들을 읽는다. BEGIN_DB { pStmt = g_pDatabaseManager->getConnection("DARKEDEN")->createStatement(); Result* pResult = pStmt->executeQuery("SELECT ZoneGroupID FROM ZoneGroupInfo ORDER BY ZoneGroupID"); while (pResult->next()) { ZoneGroupID_t ID = pResult->getInt(1); ZoneGroupIDList.push_back(ID); } SAFE_DELETE(pStmt); } END_DB(pStmt) list<ZoneGroupID_t>::iterator itr = ZoneGroupIDList.begin(); for (; itr != ZoneGroupIDList.end(); itr++) { ZoneGroupID_t ID = (*itr); // 해당하는 ID의 존 그룹을 생성하고, 매니저에다 더한다. ZoneGroup* pZoneGroup = new ZoneGroup(ID); ZonePlayerManager* pZonePlayerManager = new ZonePlayerManager(); pZonePlayerManager->setZGID(ID); pZoneGroup->setZonePlayerManager(pZonePlayerManager); addZoneGroup(pZoneGroup); // 이 존 그룹에 속하는 존의 정보를 읽어들이고, 초기화해야 한다. BEGIN_DB { pStmt = g_pDatabaseManager->getConnection("DARKEDEN")->createStatement(); //Result* pResult = pStmt->executeQuery("SELECT ZoneID FROM ZoneInfo WHERE ZoneGroupID = %d", ID); Result* pResult = pStmt->executeQuery( "SELECT ZoneID FROM ZoneInfo WHERE ZoneGroupID = %d ORDER BY ZoneID", (int)ID); while (pResult->next()) { ZoneID_t zoneID = pResult->getInt(1); // 존 객체를 생성, 초기화한 후, 존그룹에 추가한다. Zone* pZone = new Zone(zoneID); Assert(pZone != NULL); pZone->setZoneGroup(pZoneGroup); pZoneGroup->addZone(pZone); //-------------------------------------------------------------------------------- // 순서에 유의할 것. // 내부에서 NPC 를 로딩하게 되는데.. AtFirst-SetPosition 컨디션-액션을 수행할때 // ZoneGroupManager 에 접근하게 된다. 따라서, 먼저 ZGM에 추가한 후 초기화를 해야 한다. //-------------------------------------------------------------------------------- //printf("\n@@@@@@@@@@@@@@@ [%d]th ZONE INITIALIZATION START @@@@@@@@@@@@@@@\n", zoneID); pZone->init(); //printf("\n@@@@@@@@@@@@@@@ [%d]th ZONE INITIALIZATION SUCCESS @@@@@@@@@@@@@@@\n", zoneID); } SAFE_DELETE(pStmt); } END_DB(pStmt) } ZoneGroupIDList.clear(); /* Statement* pStmt1 = NULL; try { pStmt1 = g_pDatabaseManager->getConnection("DARKEDEN")->createStatement(); // ZoneGroupID 를 읽어온다. //Result* pResult1 = pStmt1->executeQuery("SELECT ZoneGroupID FROM ZoneGroupInfo ORDER BY ZoneGroupID"); Result* pResult1 = pStmt1->executeQuery("SELECT ZoneGroupID FROM ZoneGroupInfo"); while (pResult1->next()) { ZoneGroupID_t zoneGroupID = pResult1->getInt(1); // ZoneGroup 객체와 ZonePlayerManager 객체를 생성한다. ZoneGroup* pZoneGroup = new ZoneGroup(zoneGroupID); ZonePlayerManager* pZonePlayerManager = new ZonePlayerManager(); pZoneGroup->setZonePlayerManager(pZonePlayerManager); // 존그룹을 존그룹매니저에 추가한다. addZoneGroup(pZoneGroup); // 특정 ZoneGroupID 를 가진 존 정보를 읽어온다. Statement* pStmt2 = NULL; BEGIN_DB { pStmt2 = g_pDatabaseManager->getConnection("DARKEDEN")->createStatement(); Result* pResult2 = pStmt2->executeQuery("SELECT ZoneID FROM ZoneInfo WHERE ZoneGroupID = %d", zoneGroupID); while (pResult2->next()) { __BEGIN_DEBUG ZoneID_t zoneID = pResult2->getInt(1); // 존 객체를 생성, 초기화한 후, 존그룹에 추가한다. Zone* pZone = new Zone (zoneID); Assert(pZone != NULL); pZone->setZoneGroup(pZoneGroup); pZoneGroup->addZone(pZone); //-------------------------------------------------------------------------------- // 순서에 유의할 것. // 내부에서 NPC 를 로딩하게 되는데.. AtFirst-SetPosition 컨디션-액션을 수행할때 // ZoneGroupManager 에 접근하게 된다. 따라서, 먼저 ZGM에 추가한 후 초기화를 해야 한다. //-------------------------------------------------------------------------------- printf("\n@@@@@@@@@@@@@@@ [%d]th ZONE INITIALIZATION START @@@@@@@@@@@@@@@\n", zoneID); pZone->init(); printf("\n@@@@@@@@@@@@@@@ [%d]th ZONE INITIALIZATION SUCCESS @@@@@@@@@@@@@@@\n", zoneID); __END_DEBUG } SAFE_DELETE(pStmt2); } END_DB(pStmt2) } SAFE_DELETE(pStmt1); } catch (SQLQueryException & sqe) { SAFE_DELETE(pStmt1); throw Error(sqe.toString()); } */ cout << "[ZoneGroupManager] Loaded." << endl; __END_DEBUG __END_CATCH }
//--------------------------------------------------------------------------- // make DefaultLoadInfo //--------------------------------------------------------------------------- // DB에 설정된 기본 ZoneGroup으로 설정한다. //--------------------------------------------------------------------------- bool ZoneGroupManager::makeDefaultLoadInfo(LOAD_INFOS& loadInfos ) throw(Error) { __BEGIN_TRY __BEGIN_DEBUG Statement* pStmt = NULL; list<ZoneGroupID_t> ZoneGroupIDList; // 먼저 존 그룹 아이디들을 읽는다. BEGIN_DB { pStmt = g_pDatabaseManager->getConnection("DARKEDEN")->createStatement(); Result* pResult = pStmt->executeQuery("SELECT ZoneGroupID FROM ZoneGroupInfo"); while (pResult->next()) { ZoneGroupID_t ID = pResult->getInt(1); ZoneGroupIDList.push_back(ID); } SAFE_DELETE(pStmt); } END_DB(pStmt) list<ZoneGroupID_t>::iterator itr = ZoneGroupIDList.begin(); for (; itr != ZoneGroupIDList.end(); itr++) { ZoneGroupID_t ID = *itr; BEGIN_DB { pStmt = g_pDatabaseManager->getConnection("DARKEDEN")->createStatement(); //Result* pResult = pStmt->executeQuery("SELECT ZoneID FROM ZoneInfo WHERE ZoneGroupID = %d", ID); Result* pResult = pStmt->executeQuery( "SELECT ZoneID FROM ZoneInfo WHERE ZoneGroupID = %d", ID); while (pResult->next()) { ZoneID_t zoneID = pResult->getInt(1); LoadInfo* pInfo = new LoadInfo; pInfo->id = zoneID; try { pInfo->oldGroupID = g_pZoneInfoManager->getZoneInfo(zoneID)->getZoneGroupID(); } catch (NoSuchElementException& ) { filelog("makeDefaultLoadInfoError.txt", "NoSuch ZoneInfo : %d", zoneID); pInfo->oldGroupID = ID; // 그냥 넘어가게 한다. } pInfo->groupID = ID; pInfo->load = 0; // 의미없다. loadInfos[zoneID] = pInfo; } SAFE_DELETE(pStmt); } END_DB(pStmt) } ZoneGroupIDList.clear(); __END_DEBUG __END_CATCH return true; }
void CGQuitUnionAcceptHandler::execute (CGQuitUnionAccept* pPacket , Player* pPlayer) throw(Error) { __BEGIN_TRY __BEGIN_DEBUG_EX #ifdef __GAME_SERVER__ Assert(pPacket != NULL); Assert(pPlayer != NULL); GamePlayer* pGamePlayer = dynamic_cast<GamePlayer*>(pPlayer); Assert(pGamePlayer != NULL); PlayerCreature* pPlayerCreature = dynamic_cast<PlayerCreature*>(pGamePlayer->getCreature()); Assert(pPlayerCreature != NULL); #ifdef __OLD_GUILD_WAR__ GCSystemMessage gcSM; gcSM.setMessage("아직 지원되지 않는 기능입니다."); pGamePlayer->sendPacket(&gcSM); return; #endif SYSTEM_ASSERT(SYSTEM_GUILD); GCGuildResponse gcGuildResponse; GuildUnion *pUnion = GuildUnionManager::Instance().getGuildUnion(pPlayerCreature->getGuildID()); if(pUnion == NULL) { gcGuildResponse.setCode(GuildUnionOfferManager::NOT_IN_UNION); pPlayer->sendPacket(&gcGuildResponse); return; } // 요청한놈이 지가 속한 길드의 마스터인가? || 연합의 마스터길드가 내 길드가 맞나? if(!g_pGuildManager->isGuildMaster (pPlayerCreature->getGuildID(), pPlayerCreature ) || pUnion->getMasterGuildID() != pPlayerCreature->getGuildID() ) { // GC_GUILD_RESPONSE 날려준다. // 내용 : 길드 마스터가 아니자녀 -.-+ gcGuildResponse.setCode(GuildUnionOfferManager::SOURCE_IS_NOT_MASTER); pPlayer->sendPacket(&gcGuildResponse); return; } uint result = GuildUnionOfferManager::Instance().acceptQuit(pPacket->getGuildID()); gcGuildResponse.setCode(result); pPlayer->sendPacket(&gcGuildResponse); //////////////////// if(result == GuildUnionOfferManager::OK) { Guild* pGuild = g_pGuildManager->getGuild(pPacket->getGuildID()); if(pGuild == NULL) { return; } string TargetGuildMaster = pGuild->getMaster(); //cout << "연합탈퇴가 수락되었다. 통보받을 유저는 : " << TargetGuildMaster.c_str() << endl; Statement* pStmt = NULL; BEGIN_DB { pStmt = g_pDatabaseManager->getConnection("DARKEDEN" )->createStatement(); pStmt->executeQuery("INSERT INTO Messages (Receiver, Message) values('%s','%s')", TargetGuildMaster.c_str(), g_pStringPool->c_str(375 )); // 탈퇴수락한뒤에 나 혼자 남아있다면? Result *pResult = pStmt->executeQuery("SELECT count(*) FROM GuildUnionMember WHERE UnionID='%u'", pUnion->getUnionID()); pResult->next(); if(pResult->getInt(1) == 0) { //cout << "연합탈퇴가 수락된후..남아있는 멤버가 없으면..연합장이면 안되니까..지워버린다" << endl; pStmt->executeQuery("DELETE FROM GuildUnionInfo WHERE UnionID='%u'", pUnion->getUnionID()); GuildUnionManager::Instance().reload(); } SAFE_DELETE(pStmt); } END_DB(pStmt) // 연합탈퇴하면 연합정보가 바뀌었을 수도 있다. 갱신된 정보를 다시 보내준다. Creature *pCreature = NULL; pCreature = pGamePlayer->getCreature(); if(pCreature == NULL) return; GCModifyInformation gcModifyInformation; makeGCModifyInfoGuildUnion(&gcModifyInformation, pCreature); pPlayer->sendPacket(&gcModifyInformation); // 통보받을 유저에게 길드Union정보를 다시 보낸다 Creature *pTargetCreature = NULL; __ENTER_CRITICAL_SECTION((*g_pPCFinder)) pTargetCreature = g_pPCFinder->getCreature_LOCKED(TargetGuildMaster); if (pTargetCreature==NULL) { g_pPCFinder->unlock(); return; } GCModifyInformation gcModifyInformation; makeGCModifyInfoGuildUnion(&gcModifyInformation, pTargetCreature); pTargetCreature->getPlayer()->sendPacket(&gcModifyInformation); __LEAVE_CRITICAL_SECTION((*g_pPCFinder)) sendGCOtherModifyInfoGuildUnion(pTargetCreature); sendGCOtherModifyInfoGuildUnion(pCreature); // 다른 서버에 있는 놈들에게 변경사항을 알린다. GuildUnionManager::Instance().sendModifyUnionInfo(dynamic_cast<PlayerCreature*>(pTargetCreature)->getGuildID()); GuildUnionManager::Instance().sendModifyUnionInfo(dynamic_cast<PlayerCreature*>(pCreature)->getGuildID()); }
bool ActionRedeemMotorcycle::load(Item* pItem, Slayer* pSlayer, Zone* pZone, ZoneCoord_t x, ZoneCoord_t y) const throw() { bool bFound = false; __BEGIN_TRY // 단서가 되는 아이템이 키가 아니라면 false를 리턴. if (pItem->getItemClass() != Item::ITEM_CLASS_KEY) return false; Key* pKey = dynamic_cast<Key*>(pItem); ItemID_t targetID = pKey->getTarget(); try { // 키가 맞다면 키의 타겟이 되는 아이템의 아이템 ID를 얻어낸다. Statement* pStmt = NULL; Result* pResult = NULL; // targetID가 0인 경우는.. targetID(motorcycleObject의 ItemID)가 설정이 안된 경우다. // 이 때는 임시로 targetID를 key의 ItemID와 같게 하면 된다...고 본다. // targetID가 motorcycle의 itemID로 들어가기 때문에.. // broadcasting 등에서.. Assert()에 의해서 다운되었다...고 보여진다. - -; // by sigi. 2002.12.25 x-mas T_T; if (targetID==0) { targetID = pKey->setNewMotorcycle(pSlayer); /* // (!) MotorcycleObject를 생성하고 MotorcycleItemID==Target를 받아야 한다. // 이 코드 제발 함수로 빼기를.. -_-; by sigi list<OptionType_t> optionNULL; Item* pMotorcycle = g_pItemFactoryManager->createItem(Item::ITEM_CLASS_MOTORCYCLE, 0, optionNULL); Assert(pMotorcycle != NULL); (pZone->getObjectRegistry()).registerObject(pMotorcycle); pMotorcycle->create(pSlayer->getName(), STORAGE_ZONE, pZone->getZoneID(), pSlayer->getX(), pSlayer->getY()); pKey->setTarget(pMotorcycle->getItemID()); targetID = pMotorcycle->getItemID(); // targetID를 DB에도 update시켜야 한다. BEGIN_DB { pStmt = g_pDatabaseManager->getConnection("DARKEDEN")->createStatement(); pResult = pStmt->executeQuery( "UPDATE KeyObject SET Target=%d WHERE ItemID=%d", targetID, pKey->getItemID()); SAFE_DELETE(pStmt); } END_DB(pStmt) // 밑에서 pMotorcycle을 사용해도 되겠지만, 기존 코드 안 건드릴려고 여기서 지운다. SAFE_DELETE(pMotorcycle);*/ } else { // 한번 모터사이클이랑 키랑 연결됐는데 모터사이클을 누가 자꾸 지우나보다. // 키에 연결된 모터사이클이 실제로 디비에 있는지 체크하고 없으면 새로 만들어서 넣어준다. BEGIN_DB { pStmt = g_pDatabaseManager->getConnection("DARKEDEN")->createStatement(); pResult = pStmt->executeQuery("SELECT ItemID FROM MotorcycleObject WHERE ItemID=%lu", targetID); if (!pResult->next() ) { Key* pKey = dynamic_cast<Key*>(pItem); Assert(pKey != NULL); targetID = pKey->setNewMotorcycle(pSlayer); } SAFE_DELETE(pStmt); } END_DB(pStmt); } // 필살 방어 코드 -_-; if (targetID==0) { filelog("errorLog.txt", "[ActionRedeemMotorcycle] itemID=%d, motorItemID=%d", (int)pItem->getItemID(), (int)targetID); return false; } // DB에 쿼리하기 전에 먼저 객체가 생성되어 있지는 않은지 체크한다. if (g_pParkingCenter->hasMotorcycleBox(targetID)) { // 자꾸 다운되어서 혹시나 하고.. // 일단 주석처리한다. by sigi. 2002.11.16 /* if (!pSlayer->hasRideMotorcycle() && !pSlayer->isFlag(Effect::EFFECT_CLASS_COMA)) { //return false; // by sigi. 2002.11.14 MotorcycleBox* pMotorcycleBox = g_pParkingCenter->getMotorcycleBox(targetID); // 있다면 소환한다. if (pMotorcycleBox!=NULL && !pMotorcycleBox->isTransport()) { Zone* pMotorZone = pMotorcycleBox->getZone(); ZoneCoord_t motorX = pMotorcycleBox->getX(); ZoneCoord_t motorY = pMotorcycleBox->getY(); Motorcycle* pMotorcycle = pMotorcycleBox->getMotorcycle(); // 같은 존에 있는 경우 // 거리가 너무 가까우면 부르지 말자~ if (pMotorZone!=pZone || pSlayer->getDistance(motorX, motorY) > 15) { // 다른 zone으로 이동중이라고 표시한다. pMotorcycleBox->setTransport(); // motorcycle을 slayer의 zone으로 옮긴다. pMotorZone->transportItem(motorX, motorY, pMotorcycle, pZone, pSlayer->getX(), pSlayer->getY()); // Use OK 대용이다. // Use하면 아이템이 사라지던가 그렇지 싶다. - -; //GCCannotUse _GCCannotUse; //_GCCannotUse.setObjectID(pPacket->getObjectID()); //pGamePlayer->sendPacket(&_GCCannotUse); // 한동안 delay를 줘야하는데.. } } return true; } */ return false; } ItemID_t itemID; ItemType_t itemType; string optionType; Durability_t durability; BEGIN_DB { StringStream sql; sql << "SELECT ItemID, ItemType, OptionType, Durability " << "FROM MotorcycleObject where ItemID = " << targetID; pStmt = g_pDatabaseManager->getConnection("DARKEDEN")->createStatement(); pResult = pStmt->executeQuery(sql.toString()); // by sigi. 2002.10.14 // 결과물이 없다면 모터사이클이 없는 거쥐. if (pResult->getRowCount() <= 0) { bFound = false; itemID = targetID; itemType = 0; optionType = ""; durability = 300; } else { bFound = true; pResult->next(); itemID = pResult->getInt(1); itemType = pResult->getInt(2); optionType = pResult->getString(3); durability = pResult->getInt(4); } // 모터사이클 객체를 생성한다. list<OptionType_t> optionTypes; setOptionTypeFromField(optionTypes, optionType); Motorcycle* pMotorcycle = new Motorcycle(itemType, optionTypes); Assert(pMotorcycle != NULL); pMotorcycle->setItemID(itemID); pMotorcycle->setDurability(durability); // 존에다 붙이기 전에 oid를 새로 할당받는다. (pZone->getObjectRegistry()).registerObject(pMotorcycle); // 생성한 모터사이클을 존에다 갖다붙인다. TPOINT pt = pZone->addItem(pMotorcycle, x, y, false); if (pt.x == -1) { // 오토바이를 존에다 더할 수 없었다. 씨바. filelog("motorError.txt", "ActionRedeemMotorcycle::load() : 모터사이클을 존에다 더할 수 없습니다. zoneID=%d, xy=(%d, %d)", (int)pZone->getZoneID(), (int)x, (int)y); // by sigi. 2002.12.24 throw Error("ActionRedeemMotorcycle::load() : 모터사이클을 존에다 더할 수 없습니다"); } // by sigi. 2002.10.14 if (!bFound) { pStmt->executeQuery( "INSERT IGNORE INTO MotorcycleObject (ItemID, ObjectID, ItemType, OwnerID, Storage, StorageID, X, Y, OptionType, Durability) Values (%d, %d, %d, '', %d, %d, %d, %d, '', %d)", itemID, pMotorcycle->getObjectID(), itemType, STORAGE_ZONE, pZone->getZoneID(), pt.x, pt.y, durability); } // 모터사이클을 뻑킹 센터에 등록해준다. MotorcycleBox* pBox = new MotorcycleBox(pMotorcycle, pZone, pt.x, pt.y); Assert(pBox != NULL); try { g_pParkingCenter->addMotorcycleBox(pBox); } catch (DuplicatedException& de) { // by sigi. 2002.12.24 filelog("motorError.txt", "%s - itemID=%d, motorid=%d", de.toString().c_str(), itemID, pMotorcycle->getObjectID()); } bFound = true; //} SAFE_DELETE(pStmt); } END_DB(pStmt) } catch (Throwable& t) { // by sigi. 2002.12.25 filelog("motorError.txt", "%s - itemID=%d, motorItemID=%d", t.toString().c_str(), (int)pItem->getItemID(), (int)targetID); // 일단 다운은 막자. //throw; } __END_CATCH return bFound; }
void CGModifyNicknameHandler::execute (CGModifyNickname* pPacket , Player* pPlayer) throw(ProtocolException, Error) { __BEGIN_TRY __BEGIN_DEBUG_EX #ifdef __GAME_SERVER__ Assert(pPacket != NULL); Assert(pPlayer != NULL); GamePlayer* pGamePlayer = dynamic_cast<GamePlayer*>(pPlayer); Assert(pGamePlayer != NULL); PlayerCreature* pPC = dynamic_cast<PlayerCreature*>(pGamePlayer->getCreature()); Assert(pPC != NULL); Inventory* pInventory = pPC->getInventory(); Assert(pInventory != NULL); GCNicknameVerify gcNV; ObjectID_t itemOID = pPacket->getItemObjectID(); EventGiftBox* pItem = NULL; if (itemOID != 0 ) { pItem = dynamic_cast<EventGiftBox*>(pInventory->getItemWithObjectID(itemOID )); if (pItem == NULL ) { filelog("Nickname.log", "[%s:%s] 아이템이 없거나 EventGiftBox가 아닙니다.", pPlayer->getID().c_str(), pPC->getName().c_str()); gcNV.setCode(NICKNAME_MODIFY_FAIL_NO_ITEM); pGamePlayer->sendPacket(&gcNV); return; } } else { PetInfo* pPetInfo = pPC->getPetInfo(); if (pPetInfo == NULL || pPetInfo->getPetType() != PET_PACKAGE ) { gcNV.setCode(NICKNAME_MODIFY_FAIL_NO_ITEM); pGamePlayer->sendPacket(&gcNV); return; } pPetInfo->setNickname(pPacket->getNickname()); pPetInfo->getPetItem()->savePetInfo(); sendPetInfo(pGamePlayer, true); gcNV.setCode(NICKNAME_MODIFY_OK); pGamePlayer->sendPacket(&gcNV); return; } switch (pItem->getItemType() ) { // 펫 닉네임 바꾸기 case 23 : { PetInfo* pPetInfo = pPC->getPetInfo(); if (pPetInfo == NULL ) { gcNV.setCode(NICKNAME_MODIFY_FAIL_NO_ITEM); pGamePlayer->sendPacket(&gcNV); return; } if (pPetInfo->getPetType() != PET_PACKAGE && pItem == NULL ) { gcNV.setCode(NICKNAME_MODIFY_FAIL_NO_ITEM); pGamePlayer->sendPacket(&gcNV); return; } pPetInfo->setNickname(pPacket->getNickname()); pPetInfo->getPetItem()->savePetInfo(); sendPetInfo(pGamePlayer, true); gcNV.setCode(NICKNAME_MODIFY_OK); pGamePlayer->sendPacket(&gcNV); if (pPetInfo->getPetType() != PET_PACKAGE ) { pInventory->deleteItem(itemOID); pItem->destroy(); SAFE_DELETE(pItem); GCUseOK gcOK; pGamePlayer->sendPacket(&gcOK); } return; } // 커스텀 닉네임 바꾸기 case 22 : case 25 : { NicknameInfo* pNickname = pPC->getNicknameBook()->getNicknameInfo(0); if (pNickname == NULL || pNickname->getNicknameType() != NicknameInfo::NICK_CUSTOM || pPacket->getNickname() == "" ) { gcNV.setCode(NICKNAME_MODIFY_FAIL_NO_ITEM); pGamePlayer->sendPacket(&gcNV); return; } if (pItem == NULL ) { gcNV.setCode(NICKNAME_MODIFY_FAIL_NO_ITEM); pGamePlayer->sendPacket(&gcNV); return; } // pPC->removeFlag(Effect::EFFECT_CLASS_CAN_MODIFY_NICKNAME_0); pNickname->setNickname(pPacket->getNickname()); Statement* pStmt = NULL; BEGIN_DB { pStmt = g_pDatabaseManager->getConnection("DARKEDEN")->createStatement(); pStmt->executeQuery("UPDATE NicknameBook SET Nickname='%s' WHERE OwnerID='%s' AND nID=%u", getDBString(pNickname->getNickname()).c_str(), pPC->getName().c_str(), pNickname->getNicknameID()); SAFE_DELETE(pStmt); } END_DB(pStmt) gcNV.setCode(NICKNAME_MODIFY_OK); pGamePlayer->sendPacket(&gcNV); if (pItem->getItemType() == 22 ) { pInventory->deleteItem(itemOID); pItem->destroy(); SAFE_DELETE(pItem); GCUseOK gcOK; pGamePlayer->sendPacket(&gcOK); } if (pPC->getNickname() == pNickname ) { GCModifyNickname gcMN; gcMN.setObjectID(pPC->getObjectID()); gcMN.setNicknameInfo(pNickname); pPC->getZone()->broadcastPacket(pPC->getX(), pPC->getY(), &gcMN); } break; } // 닉네임 추가하기 case 24 : { if (pItem == NULL ) { gcNV.setCode(NICKNAME_MODIFY_FAIL_NO_ITEM); pGamePlayer->sendPacket(&gcNV); return; } NicknameInfo* pNickname = new NicknameInfo; pNickname->setNicknameID(pPC->getNicknameBook()->popNicknameID()); pNickname->setNicknameType(NicknameInfo::NICK_CUSTOM); pNickname->setNickname(pPacket->getNickname()); pPC->getNicknameBook()->setNicknameInfo(pNickname->getNicknameID(), pNickname); Statement* pStmt = NULL; BEGIN_DB { pStmt = g_pDatabaseManager->getConnection("DARKEDEN")->createStatement(); pStmt->executeQuery("INSERT INTO NicknameBook (nID, OwnerID, NickType, Nickname, Time) " "VALUES (%u, '%s', %u, '%s', now())", pNickname->getNicknameID(), pPC->getName().c_str(), pNickname->getNicknameType(), getDBString(pNickname->getNickname()).c_str()); SAFE_DELETE(pStmt); } END_DB(pStmt) gcNV.setCode(NICKNAME_MODIFY_OK); pGamePlayer->sendPacket(&gcNV); Packet* pNickList = pPC->getNicknameBook()->getNicknameBookListPacket(); pGamePlayer->sendPacket(pNickList); SAFE_DELETE(pNickList); pInventory->deleteItem(itemOID); pItem->destroy(); SAFE_DELETE(pItem); GCUseOK gcOK; pGamePlayer->sendPacket(&gcOK); break; } } #endif // __GAME_SERVER__ __END_DEBUG_EX __END_CATCH }
////////////////////////////////////////////////////////////////////////////// // 슬레이어 오브젝트 핸들러 ////////////////////////////////////////////////////////////////////////////// void Restore::execute(Slayer* pSlayer, ObjectID_t TargetObjectID, SkillSlot* pSkillSlot, CEffectID_t CEffectID) throw(Error) { __BEGIN_TRY //cout << "TID[" << Thread::self() << "]" << getSkillHandlerName() << " Begin" << endl; //cout << "Restore2 Start" << endl; Assert(pSlayer != NULL); Assert(pSkillSlot != NULL); try { Player* pPlayer = pSlayer->getPlayer(); Zone* pZone = pSlayer->getZone(); Assert(pPlayer != NULL); Assert(pZone != NULL); Creature* pFromCreature = pZone->getCreature(TargetObjectID); // 뱀파이어만 건드릴 수가 있다. // NoSuch제거. by sigi. 2002.5.2 if (pFromCreature==NULL || !pFromCreature->isVampire()) { executeSkillFailException(pSlayer, getSkillType()); //cout << "TID[" << Thread::self() << "]" << getSkillHandlerName() << " End" << endl; return; } GCSkillToObjectOK1 _GCSkillToObjectOK1; // 스킬 쓴 넘에게... GCMorph1 _GCMorph1; // 변신 당사자에게.. GCMorphSlayer2 _GCMorphSlayer2; // 변신 구경꾼들에게.. SkillType_t SkillType = pSkillSlot->getSkillType(); SkillInfo* pSkillInfo = g_pSkillInfoManager->getSkillInfo(SkillType); bool bRangeCheck = verifyDistance(pSlayer, pFromCreature, pSkillInfo->getRange()); bool bHitRoll = true; if (bRangeCheck && bHitRoll) { ////////////////////////////////////////////////////////////////////// // 각종 존 레벨 정보를 삭제해야 한다. ////////////////////////////////////////////////////////////////////// // 파티 초대 중이라면 정보를 삭제해 준다. PartyInviteInfoManager* pPIIM = pZone->getPartyInviteInfoManager(); Assert(pPIIM != NULL); pPIIM->cancelInvite(pFromCreature); // 파티 관련 정보를 삭제해 준다. int PartyID = pFromCreature->getPartyID(); if (PartyID != 0) { // 먼저 로컬에서 삭제하고... LocalPartyManager* pLPM = pZone->getLocalPartyManager(); Assert(pLPM != NULL); pLPM->deletePartyMember(PartyID, pFromCreature); // 글로벌에서도 삭제해 준다. deleteAllPartyInfo(pFromCreature); } // 트레이드 중이었다면 트레이드 관련 정보를 삭제해준다. TradeManager* pTM = pZone->getTradeManager(); Assert(pTM != NULL); pTM->cancelTrade(pFromCreature); ////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////// Slayer* pNewSlayer = new Slayer; Vampire* pVampire = dynamic_cast<Vampire*>(pFromCreature); // DB에서 혹시 남아있을 지 모르는 흡혈 정보를 삭제해준다. Statement* pStmt = NULL; BEGIN_DB { pStmt = g_pDatabaseManager->getConnection("DARKEDEN")->createStatement(); StringStream sql; sql << "DELETE FROM EffectBloodDrain WHERE OwnerID = '" + pFromCreature->getName() + "'"; pStmt->executeQuery(sql.toString()); SAFE_DELETE(pStmt); } END_DB(pStmt) pNewSlayer->setName(pFromCreature->getName()); // 크리쳐 안의 플레이어 포인터와 플레이어 안의 크리쳐 포인터를 갱신한다. Player* pFromPlayer = pFromCreature->getPlayer(); pNewSlayer->setPlayer(pFromPlayer); GamePlayer* pFromGamePlayer = dynamic_cast<GamePlayer*>(pFromPlayer); pFromGamePlayer->setCreature(pNewSlayer); pNewSlayer->setZone(pZone); pNewSlayer->load(); pNewSlayer->setObjectID(pFromCreature->getObjectID()); pNewSlayer->setMoveMode(Creature::MOVE_MODE_WALKING); ZoneCoord_t x = pFromCreature->getX(); ZoneCoord_t y = pFromCreature->getY(); Dir_t dir = pFromCreature->getDir(); Tile& tile = pZone->getTile(x, y); // 곧 pFromCreature 즉, 원래의 뱀파이어 객체는 지워질 것이므로, // PCFinder에 들어가 있는 값은 쓰레기 값이 될 것이다. // 그러므로 뱀파이어 포인터를 지워주고, 새로운 슬레이어 포인터를 더한다. g_pPCFinder->deleteCreature(pFromCreature->getName()); g_pPCFinder->addCreature(pNewSlayer); // 길드 현재 접속 멤버 리스트에서 삭제한다. if (pVampire->getGuildID() != 0 ) g_pGuildManager->getGuild(pVampire->getGuildID() )->deleteCurrentMember(pVampire->getName()); // 인벤토리 교체. Inventory* pInventory = pVampire->getInventory(); pNewSlayer->setInventory(pInventory); pVampire->setInventory(NULL); // 보관함 교체 pNewSlayer->deleteStash(); pNewSlayer->setStash(pVampire->getStash()); pNewSlayer->setStashNum(pVampire->getStashNum()); pNewSlayer->setStashStatus(false); pVampire->setStash(NULL); /* // 가비지 교체 while (true) { Item* pGarbage = pVampire->popItemFromGarbage(); // 더 이상 없다면 브레이크... if (pGarbage == NULL) break; pNewSlayer->addItemToGarbage(pGarbage); } */ // 플래그 셋 교체 pNewSlayer->deleteFlagSet(); pNewSlayer->setFlagSet(pVampire->getFlagSet()); pVampire->setFlagSet(NULL); Item* pItem = NULL; _TPOINT point; // 입고 있는 아이템들을 인벤토리 또는 바닥으로 옮긴다. for(int part = 0; part < (int)Vampire::VAMPIRE_WEAR_MAX; part++) { pItem = pVampire->getWearItem((Vampire::WearPart)part); if (pItem != NULL) { // 먼저 기어에서 삭제하고... pVampire->deleteWearItem((Vampire::WearPart)part); // 인벤토리에 자리가 있으면 인벤토리에 더하고... if (pInventory->getEmptySlot(pItem, point)) { pInventory->addItem(point.x, point.y, pItem); pItem->save(pNewSlayer->getName(), STORAGE_INVENTORY, 0, point.x, point.y); } // 자리가 없으면 바닥에 떨어뜨린다. else { ZoneCoord_t ZoneX = pVampire->getX(); ZoneCoord_t ZoneY = pVampire->getY(); TPOINT pt; pt = pZone->addItem(pItem, ZoneX , ZoneY); if (pt.x != -1) { pItem->save("", STORAGE_ZONE, pZone->getZoneID(), pt.x, pt.y); } else { pItem->destroy(); SAFE_DELETE(pItem); } } } } pItem = pVampire->getExtraInventorySlotItem(); if (pItem != NULL) { pVampire->deleteItemFromExtraInventorySlot(); // 인벤토리에 자리가 있으면 인벤토리에 더하고... if (pInventory->getEmptySlot(pItem, point)) { pInventory->addItem(point.x, point.y, pItem); pItem->save(pNewSlayer->getName(), STORAGE_INVENTORY, 0, point.x, point.y); } // 자리가 없으면 바닥에 떨어뜨린다. else { TPOINT pt; ZoneCoord_t ZoneX = pVampire->getX(); ZoneCoord_t ZoneY = pVampire->getY(); pt = pZone->addItem(pItem, ZoneX , ZoneY); if (pt.x != -1) { pItem->save("", STORAGE_ZONE, pZone->getZoneID(), pt.x, pt.y); } else { pItem->destroy(); SAFE_DELETE(pItem); } } } // 뱀파이어 가지고 있던 돈을 슬레이어로 옮겨준다. pNewSlayer->setGoldEx(pVampire->getGold()); // 스킬 정보를 전송한다. pNewSlayer->sendSlayerSkillInfo(); _GCMorph1.setPCInfo2(pNewSlayer->getSlayerInfo2()); _GCMorph1.setInventoryInfo(pNewSlayer->getInventoryInfo()); _GCMorph1.setGearInfo(pNewSlayer->getGearInfo()); _GCMorph1.setExtraInfo(pNewSlayer->getExtraInfo()); _GCMorphSlayer2.setSlayerInfo(pNewSlayer->getSlayerInfo3()); pFromPlayer->sendPacket(&_GCMorph1); //pFromGamePlayer->deleteEvent(Event::EVENT_CLASS_REGENERATION); pZone->broadcastPacket(x, y, &_GCMorphSlayer2, pNewSlayer); // 타일 및 존에서 기존 뱀파이어를 삭제하고, 새로운 슬레이어를 더한다. tile.deleteCreature(pFromCreature->getObjectID()); pZone->deletePC(pFromCreature); TPOINT pt = findSuitablePosition(pZone, x, y, Creature::MOVE_MODE_WALKING); Tile& newtile = pZone->getTile(pt.x, pt.y); newtile.addCreature(pNewSlayer); pNewSlayer->setXYDir(pt.x, pt.y, dir); pZone->addPC(pNewSlayer); pNewSlayer->tinysave("Race='SLAYER'"); SAFE_DELETE(pFromCreature); // 시야 update.. pZone->updateHiddenScan(pNewSlayer); _GCSkillToObjectOK1.setSkillType(SkillType); _GCSkillToObjectOK1.setCEffectID(CEffectID); _GCSkillToObjectOK1.setTargetObjectID(TargetObjectID); _GCSkillToObjectOK1.setDuration(0); pPlayer->sendPacket(&_GCSkillToObjectOK1); pSkillSlot->setRunTime(0); EffectRestore* pEffectRestore = new EffectRestore(pNewSlayer); pEffectRestore->setDeadline(60*60*24*7*10); // 7일 pNewSlayer->addEffect(pEffectRestore); pNewSlayer->setFlag(Effect::EFFECT_CLASS_RESTORE); pEffectRestore->create(pNewSlayer->getName()); } else { executeSkillFailNormal(pSlayer, getSkillType(), pFromCreature); } }
void CGLotterySelectHandler::execute (CGLotterySelect* pPacket , Player* pPlayer) throw(Error) { __BEGIN_TRY __BEGIN_DEBUG_EX #ifdef __GAME_SERVER__ GamePlayer* pGP = dynamic_cast<GamePlayer*>(pPlayer); Assert(pGP != NULL); Creature* pCreature = pGP->getCreature(); Assert(pCreature != NULL); PlayerCreature* pPC = dynamic_cast<PlayerCreature*>(pCreature); Assert(pPC != NULL); filelog("EventQuest.log", "CGLotterySelectHandler : got [%d:%d:%d] from %s", pPacket->getType(), pPacket->getGiftID(), pPacket->getQuestLevel(), pPC->getName().c_str()); switch (pPacket->getType() ) { case TYPE_SELECT_LOTTERY: { // 인벤에서 퀘스트 아이템 삭제 QuestID_t qID; EventQuestAdvance::Status status = pPC->getQuestManager()->getEventQuestAdvanceManager()->getStatus(pPacket->getQuestLevel()); int ownerQuestLevel = pPC->getQuestManager()->getEventQuestAdvanceManager()->getQuestLevel(); if ( (ownerQuestLevel > pPacket->getQuestLevel() && status == EventQuestAdvance::EVENT_QUEST_ADVANCED ) || (pPacket->getQuestLevel() == 4 && ownerQuestLevel== -1 ) || pPC->getQuestManager()->successEventQuest(pPacket->getQuestLevel(), qID ) ) { pPC->getQuestManager()->getEventQuestAdvanceManager()->rewarded(pPacket->getQuestLevel()); pPC->getQuestManager()->getEventQuestAdvanceManager()->save(); pPC->getQuestManager()->questRewarded(qID); pPC->sendCurrentQuestInfo(); list<Item*> iList; pPC->getInventory()->clearQuestItem(iList); list<Item*>::iterator itr = iList.begin(); list<Item*>::iterator endItr = iList.end(); for (; itr != endItr ; ++itr ) { GCDeleteInventoryItem gcDII; gcDII.setObjectID((*itr)->getObjectID()); pPC->getPlayer()->sendPacket(&gcDII); (*itr)->destroy(); SAFE_DELETE(*itr); } iList.clear(); } else { filelog("EventBug.txt", "CGLotterySelectHandler : 복권 선택이 날라왔는데 완료한 퀘스트가 없다. -_-; %s[%d:%d]", pPC->getName().c_str(), pPacket->getQuestLevel(), pPacket->getGiftID()); return; } GCNoticeEvent gcNE; gcNE.setCode(NOTICE_EVENT_RESULT_LOTTERY); if (bWinPrize(pPacket->getGiftID(), pPacket->getQuestLevel() ) ) { // PlayerCreature 에 정보를 저장한다 pPC->setLotto(true); pPC->setLottoRewardID(pPacket->getGiftID()); pPC->setLottoQuestLevel(pPacket->getQuestLevel()); gcNE.setParameter((uint)1); } else { // PlayerCreature 에 정보를 저장한다 pPC->setLotto(false); pPC->setLottoRewardID(pPacket->getGiftID()); pPC->setLottoQuestLevel(pPacket->getQuestLevel()); gcNE.setParameter((uint)0); } pGP->sendPacket(&gcNE); filelog("EventQuest.log", "CGLotterySelectHandler : %d to %s", gcNE.getParameter(), pPC->getName().c_str()); } break; case TYPE_FINISH_SCRATCH: { // 당첨된 경우 디비에 저장 if (pPC->isLotto() ) { // 다시 false 로 만들어줘야함. // 아님 담번 퀘스트에서 무조건 당첨으로 처리되니 ;; pPC->setLotto(false); Statement* pStmt = NULL; BEGIN_DB { pStmt = g_pDatabaseManager->getConnection("DARKEDEN")->createStatement(); pStmt->executeQuery("INSERT INTO EventQuestRewardRecord (PlayerID, RewardID, Time, RealPlayerID) VALUES ('%s', %d, now(), '%s' )", pCreature->getName().c_str(), pPC->getLottoRewardID(), pPC->getPlayer()->getID().c_str()); SAFE_DELETE(pStmt); } END_DB(pStmt) // 이쪽 서버에 브로드 캐스트 하고 (allworld 는 해당 서버는 처리 안함) GCNotifyWin gcNW; gcNW.setGiftID(pPC->getLottoRewardID()); gcNW.setName(pCreature->getName()); g_pZoneGroupManager->broadcast(&gcNW); // 전 월드에 브로드캐스트해준다 char sCommand[200]; string worldName = g_pGameWorldInfoManager->getGameWorldInfo(g_pConfig->getPropertyInt("WorldID" ))->getName(); sprintf(sCommand, "*allworld *command NotifyWin %s(%s) %lu", pCreature->getName().c_str(), worldName.c_str(), pPC->getLottoRewardID()); CGSayHandler::opworld(NULL, sCommand, 0, false); } else { // 아니면 그냥 퀘스트 아이템만 인벤에 넣어주면 되는듯 Item::ItemClass iClass; ItemType_t iType; list<OptionType_t> oList; bool isTimeLimit = false; bool isLairItem = false; bool isUnique = false; MonsterType_t masterType; switch(pPC->getLottoQuestLevel() ) // switch(pPC->getQuestManager()->getEventQuestAdvanceManager()->getQuestLevel() ) { case 0: { static const string options1[] = { "STR+2", "DEX+2", "INT+2", "ASPD+2", "HP+2" }; static const string options2[] = { "STR+3", "DEX+3", "INT+3", "ASPD+3", "HP+3" }; if (pPC->isSlayer() ) { Slayer* pSlayer = dynamic_cast<Slayer*>(pPC); QuestGrade_t qGrade = pSlayer->getTotalAttr(ATTR_BASIC); iClass = Item::ITEM_CLASS_RING; if (qGrade < 131 ) { iType = 1; makeOptionList(options1[ rand()%5 ], oList); } else if (qGrade < 211 ) { iType = 2; makeOptionList(options1[ rand()%5 ], oList); } else if (qGrade < 271 ) { iType = 3; makeOptionList(options2[ rand()%5 ], oList); } else if (qGrade < 300 ) { iType = 4; makeOptionList(options2[ rand()%5 ], oList); } else { iType = 5; makeOptionList(options2[ rand()%5 ], oList); } } else if (pPC->isVampire() ) { Vampire* pVampire = dynamic_cast<Vampire*>(pPC); Level_t level = pVampire->getLevel(); iClass = Item::ITEM_CLASS_VAMPIRE_RING; if (level < 31 ) { iType = 1; makeOptionList(options1[ rand()%5 ], oList); } else if (level < 51 ) { iType = 2; makeOptionList(options1[ rand()%5 ], oList); } else if (level < 71 ) { iType = 3; makeOptionList(options2[ rand()%5 ], oList); } else if (level < 91 ) { iType = 4; makeOptionList(options2[ rand()%5 ], oList); } else { iType = 5; makeOptionList(options2[ rand()%5 ], oList); } } else if (pPC->isOusters() ) { Ousters* pOusters = dynamic_cast<Ousters*>(pPC); Level_t level = pOusters->getLevel(); iClass = Item::ITEM_CLASS_OUSTERS_RING; if (level < 31 ) { iType = 1; makeOptionList(options1[ rand()%5 ], oList); } else if (level < 51 ) { iType = 2; makeOptionList(options1[ rand()%5 ], oList); } else if (level < 71 ) { iType = 3; makeOptionList(options2[ rand()%5 ], oList); } else if (level < 91 ) { iType = 4; makeOptionList(options2[ rand()%5 ], oList); } else { iType = 5; makeOptionList(options2[ rand()%5 ], oList); } } } break; case 1: { static const string oSlayer1[] = { "DAM+2", "VIS+3", "MP+2", "LUCK+1", "HP+2" }; static const string oSlayer2[] = { "DAM+3", "VIS+3", "MP+3", "LUCK+2", "HP+3" }; static const string oVampire1[] = { "DAM+2", "VIS+3", "ASPD+2", "LUCK+1", "HP+2" }; static const string oVampire2[] = { "DAM+3", "VIS+3", "ASPD+3", "LUCK+2", "HP+3" }; if (pPC->isSlayer() ) { Slayer* pSlayer = dynamic_cast<Slayer*>(pPC); QuestGrade_t qGrade = pSlayer->getTotalAttr(ATTR_BASIC); iClass = Item::ITEM_CLASS_RING; if (qGrade < 131 ) { iType = 2; makeOptionList(oSlayer1[ rand()%5 ], oList); } else if (qGrade < 211 ) { iType = 3; makeOptionList(oSlayer1[ rand()%5 ], oList); } else if (qGrade < 271 ) { iType = 4; makeOptionList(oSlayer2[ rand()%5 ], oList); } else if (qGrade < 300 ) { iType = 5; makeOptionList(oSlayer2[ rand()%5 ], oList); } else { iType = 6; makeOptionList(oSlayer2[ rand()%5 ], oList); } } else if (pPC->isVampire() ) { Vampire* pVampire = dynamic_cast<Vampire*>(pPC); Level_t level = pVampire->getLevel(); iClass = Item::ITEM_CLASS_VAMPIRE_RING; if (level < 31 ) { iType = 2; makeOptionList(oVampire1[ rand()%5 ], oList); } else if (level < 51 ) { iType = 3; makeOptionList(oVampire1[ rand()%5 ], oList); } else if (level < 71 ) { iType = 4; makeOptionList(oVampire2[ rand()%5 ], oList); } else if (level < 91 ) { iType = 5; makeOptionList(oVampire2[ rand()%5 ], oList); } else { iType = 6; makeOptionList(oVampire2[ rand()%5 ], oList); } } else if (pPC->isOusters() ) { Ousters* pOusters = dynamic_cast<Ousters*>(pPC); Level_t level = pOusters->getLevel(); iClass = Item::ITEM_CLASS_OUSTERS_RING; if (level < 31 ) { iType = 2; makeOptionList(oVampire1[ rand()%5 ], oList); } else if (level < 51 ) { iType = 3; makeOptionList(oVampire1[ rand()%5 ], oList); } else if (level < 71 ) { iType = 4; makeOptionList(oVampire2[ rand()%5 ], oList); } else if (level < 91 ) { iType = 5; makeOptionList(oVampire2[ rand()%5 ], oList); } else { iType = 6; makeOptionList(oVampire2[ rand()%5 ], oList); } } } break; case 2: { isLairItem = true; masterType = 432; } break; case 3: { isLairItem = true; masterType = 433; } break; case 4: { isTimeLimit = true; if (pPC->isSlayer() ) { isUnique = true; static const Item::ItemClass iClasses[] = { Item::ITEM_CLASS_COAT, Item::ITEM_CLASS_TROUSER, Item::ITEM_CLASS_GLOVE, Item::ITEM_CLASS_HELM, Item::ITEM_CLASS_SHOES, // Item::ITEM_CLASS_BELT, Item::ITEM_CLASS_NECKLACE, Item::ITEM_CLASS_BRACELET }; static const ItemType_t iTypes[] = { 16, 16, 8, 9, 7, // 4, 10, 10 }; int index = rand() % 7; iClass = iClasses[index]; iType = iTypes[index]; } else if (pPC->isVampire() ) { isUnique = true; static const Item::ItemClass iClasses[] = { Item::ITEM_CLASS_VAMPIRE_COAT, Item::ITEM_CLASS_VAMPIRE_WEAPON, Item::ITEM_CLASS_VAMPIRE_RING, Item::ITEM_CLASS_VAMPIRE_NECKLACE, Item::ITEM_CLASS_VAMPIRE_BRACELET, Item::ITEM_CLASS_VAMPIRE_AMULET, Item::ITEM_CLASS_VAMPIRE_EARRING }; static const ItemType_t iTypes[] = { 12, 15, 10, 10, 9, 10, 10 }; int index = rand() % 7; iClass = iClasses[index]; iType = iTypes[index]; } else if (pPC->isOusters() ) { static const Item::ItemClass iClasses[] = { Item::ITEM_CLASS_OUSTERS_COAT, Item::ITEM_CLASS_OUSTERS_CIRCLET, Item::ITEM_CLASS_OUSTERS_ARMSBAND, Item::ITEM_CLASS_OUSTERS_BOOTS, Item::ITEM_CLASS_OUSTERS_PENDENT, Item::ITEM_CLASS_OUSTERS_RING }; static const ItemType_t iTypes[] = { 7, 9, 9, 7, 9, 9 }; static const string options[] = { "DAM+3", "ASPD+3", "LUCK+2", "HP+9", "STR+3", "DEX+3", "INT+3", "ATTR+2", "RES+3", "MP+4" }; int index = rand() % 6; iClass = iClasses[index]; iType = iTypes[index]; int option1 = rand()%10; int option2 = rand()%10; while (option1 == option2 ) option2 = rand()%10; makeOptionList(options[ option1 ] + "," + options[ option2 ], oList); } } break; default: break; } Item* pItem; if (isLairItem ) { const MonsterInfo* pMonsterInfo = g_pMonsterInfoManager->getMonsterInfo(masterType); TreasureList *pTreasureList = NULL; if (pPC->isSlayer()) pTreasureList = pMonsterInfo->getSlayerTreasureList(); else if (pPC->isVampire() ) pTreasureList = pMonsterInfo->getVampireTreasureList(); else if (pPC->isOusters() ) pTreasureList = pMonsterInfo->getOustersTreasureList(); const list<Treasure*>& treasures = pTreasureList->getTreasures(); list<Treasure*>::const_iterator itr = treasures.begin(); ITEM_TEMPLATE it; for(; itr != treasures.end(); itr++) { Treasure* pTreasure = (*itr); it.ItemClass = Item::ITEM_CLASS_MAX; it.ItemType = 0; it.NextOptionRatio = 0; //cout << "TradeLairItem: BonusRatio = " << it.NextOptionRatio << endl; if (pTreasure->getRandomItem(&it) ) { pItem = g_pItemFactoryManager->createItem(it.ItemClass, it.ItemType, it.OptionType); Assert(pItem != NULL); } } } else { pItem = g_pItemFactoryManager->createItem(iClass, iType, oList); } GenderRestriction gender = GENDER_BOTH; switch(pPC->getSex() ) { case MALE: gender = GENDER_MALE; break; case FEMALE: gender = GENDER_FEMALE; break; default: break; } setItemGender(pItem, gender); _TPOINT tp; if (pItem != NULL && pPC->getInventory()->addItem(pItem, tp ) ) { pPC->getZone()->registerObject(pItem); pItem->create(pPC->getName(), STORAGE_INVENTORY, 0, tp.x, tp.y); if (isTimeLimit ) { pPC->addTimeLimitItem(pItem, 604800); pPC->sendTimeLimitItemInfo(); } GCCreateItem gcCreateItem; makeGCCreateItem(&gcCreateItem, pItem, tp.x, tp.y); pPC->getPlayer()->sendPacket(&gcCreateItem); remainTraceLog(pItem, "GOD", pCreature->getName(), ITEM_LOG_CREATE, DETAIL_EVENTNPC); } else { if (isUnique ) pItem->setUnique(); if (isTimeLimit ) pItem->setTimeLimitItem(); pPC->setQuestItem(pItem); remainTraceLog(pItem, "GOD", pCreature->getName(), ITEM_LOG_CREATE, DETAIL_EVENTNPC); } } if (pPC->getLottoQuestLevel() == 4 ) { pPC->getQuestManager()->cancelQuest(); GCNoticeEvent gcNE; gcNE.setCode(NOTICE_EVENT_START_QUEST_ENDING); pPC->getPlayer()->sendPacket(&gcNE); } }
bool GuildUnionManager::removeMasterGuild(GuildID_t gID) throw(Error) { __BEGIN_TRY // 내가 길드연합장인데..내가 탈퇴한다면.. // 내가 속한 길드연합을 깨보자.. GuildUnion* pUnion = m_GuildUnionMap[gID]; // 내가 마스터인 연합이 있다면 -> 내 연합에 소속된 모든 길드를 out시키고 내 연합을 깨버린다. if(pUnion != NULL) { uint uID = pUnion->getUnionID(); // 연합ID Statement* pStmt = NULL; BEGIN_DB { Result *pResult = NULL; pStmt = g_pDatabaseManager->getConnection("DARKEDEN")->createStatement(); pResult = pStmt->executeQuery("SELECT OwnerGuildID FROM GuildUnionMember WHERE UnionID = %u", uID); // 아무것도 없다면 이상한거다.. if (pResult->getRowCount() == 0 ) { SAFE_DELETE(pStmt); return false; } string unionMasterID = g_pGuildManager->getGuild(gID )->getMaster(); // 각각의 모든 길드들을 연합에서 탈퇴시킨다. // 모두 지워지면 연합도 알아서 깨진다. while (pResult->next() ) { if (pUnion->removeGuild(pResult->getInt(1) ) ) { m_GuildUnionMap[gID] = NULL; if (pUnion->m_Guilds.empty() ) { list<GuildUnion*>::iterator itr = find(m_GuildUnionList.begin(), m_GuildUnionList.end(), pUnion); if(itr != m_GuildUnionList.end() ) { pUnion->destroy(); m_GuildUnionList.erase(itr); m_GuildUnionMap.erase (pUnion->getMasterGuildID()); m_UnionIDMap.erase (pUnion->getUnionID()); SAFE_DELETE(pUnion); } // } // isEmpty sendGCOtherModifyInfoGuildUnionByGuildID(pResult->getInt(1)); } // if } // while // 모든 길드를 다 제거한다. 마지막에 남은 길드까지 깨끗히 청소하고 나면 Creature *pTargetCreature = NULL; __ENTER_CRITICAL_SECTION((*g_pPCFinder)) pTargetCreature = g_pPCFinder->getCreature_LOCKED(unionMasterID); if (pTargetCreature!=NULL) { GCModifyInformation gcModifyInformation2; makeGCModifyInfoGuildUnion(&gcModifyInformation2, pTargetCreature); pTargetCreature->getPlayer()->sendPacket(&gcModifyInformation2); } __LEAVE_CRITICAL_SECTION((*g_pPCFinder)) // 연합마스터 바뀐정보를 보내줘보자.. sendGCOtherModifyInfoGuildUnionByGuildID(gID); sendRefreshCommand(); } END_DB(pStmt); }
////////////////////////////////////////////////////////////////////////////// // 슬레이어 오브젝트 핸들러 ////////////////////////////////////////////////////////////////////////////// void Restore::execute(Slayer* pSlayer, ObjectID_t TargetObjectID, SkillSlot* pSkillSlot, CEffectID_t CEffectID) throw(Error) { __BEGIN_TRY //cout << "TID[" << Thread::self() << "]" << getSkillHandlerName() << " Begin" << endl; Assert(pSlayer != NULL); Assert(pSkillSlot != NULL); try { Player* pPlayer = pSlayer->getPlayer(); Zone* pZone = pSlayer->getZone(); Assert(pPlayer != NULL); Assert(pZone != NULL); Creature* pFromCreature = pZone->getCreature(TargetObjectID); // 뱀파이어만 건드릴 수가 있다. // NoSuch제거. by sigi. 2002.5.2 if (pFromCreature==NULL || !pFromCreature->isVampire()) { executeSkillFailException(pSlayer, getSkillType()); //cout << "TID[" << Thread::self() << "]" << getSkillHandlerName() << " End" << endl; return; } GCSkillToObjectOK1 _GCSkillToObjectOK1; // 스킬 쓴 넘에게... GCMorph1 _GCMorph1; // 변신 당사자에게.. GCMorphSlayer2 _GCMorphSlayer2; // 변신 구경꾼들에게.. SkillType_t SkillType = pSkillSlot->getSkillType(); SkillInfo* pSkillInfo = g_pSkillInfoManager->getSkillInfo(SkillType); bool bRangeCheck = verifyDistance(pSlayer, pFromCreature, pSkillInfo->getRange()); bool bHitRoll = true; if (bRangeCheck && bHitRoll) { dropRelicToZone(pFromCreature); dropFlagToZone(pFromCreature); ////////////////////////////////////////////////////////////////////// // 각종 존 레벨 정보를 삭제해야 한다. ////////////////////////////////////////////////////////////////////// // 파티 초대 중이라면 정보를 삭제해 준다. PartyInviteInfoManager* pPIIM = pZone->getPartyInviteInfoManager(); Assert(pPIIM != NULL); pPIIM->cancelInvite(pFromCreature); // 파티 관련 정보를 삭제해 준다. int PartyID = pFromCreature->getPartyID(); if (PartyID != 0) { // 먼저 로컬에서 삭제하고... LocalPartyManager* pLPM = pZone->getLocalPartyManager(); Assert(pLPM != NULL); pLPM->deletePartyMember(PartyID, pFromCreature); // 글로벌에서도 삭제해 준다. deleteAllPartyInfo(pFromCreature); } // 트레이드 중이었다면 트레이드 관련 정보를 삭제해준다. TradeManager* pTM = pZone->getTradeManager(); Assert(pTM != NULL); pTM->cancelTrade(pFromCreature); ////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////// Slayer* pNewSlayer = new Slayer; Vampire* pVampire = dynamic_cast<Vampire*>(pFromCreature); // DB에서 혹시 남아있을 지 모르는 흡혈 정보를 삭제해준다. Statement* pStmt = NULL; BEGIN_DB { pStmt = g_pDatabaseManager->getConnection("DARKEDEN")->createStatement(); StringStream sql; sql << "DELETE FROM EffectBloodDrain WHERE OwnerID = '" + pFromCreature->getName() + "'"; pStmt->executeQuery(sql.toString()); SAFE_DELETE(pStmt); } END_DB(pStmt) pNewSlayer->setName(pFromCreature->getName()); // 크리쳐 안의 플레이어 포인터와 플레이어 안의 크리쳐 포인터를 갱신한다. Player* pFromPlayer = pFromCreature->getPlayer(); pNewSlayer->setPlayer(pFromPlayer); GamePlayer* pFromGamePlayer = dynamic_cast<GamePlayer*>(pFromPlayer); pFromGamePlayer->setCreature(pNewSlayer); // load하면 load한 zone에서 objectID를 받으므로 다시 설정한다. by sigi. 2002.6.4 pNewSlayer->load(); pNewSlayer->setZone(pZone); pNewSlayer->setObjectID(pFromCreature->getObjectID()); //pZone->getObjectRegistry().registerObject(pNewSlayer); pNewSlayer->setMoveMode(Creature::MOVE_MODE_WALKING); ZoneCoord_t x = pFromCreature->getX(); ZoneCoord_t y = pFromCreature->getY(); Dir_t dir = pFromCreature->getDir(); Tile& tile = pZone->getTile(x, y); // 곧 pFromCreature 즉, 원래의 뱀파이어 객체는 지워질 것이므로, // PCFinder에 들어가 있는 값은 쓰레기 값이 될 것이다. // 그러므로 뱀파이어 포인터를 지워주고, 새로운 슬레이어 포인터를 더한다. g_pPCFinder->deleteCreature(pFromCreature->getName()); g_pPCFinder->addCreature(pNewSlayer); // 길드 현재 접속 멤버 리스트에서 삭제한다. if (pVampire->getGuildID() != 0 ) { Guild* pGuild = g_pGuildManager->getGuild(pVampire->getGuildID()); if (pGuild != NULL ) { pGuild->deleteCurrentMember(pVampire->getName()); GSGuildMemberLogOn gsGuildMemberLogOn; gsGuildMemberLogOn.setGuildID(pGuild->getID()); gsGuildMemberLogOn.setName(pVampire->getName()); gsGuildMemberLogOn.setLogOn(false); g_pSharedServerManager->sendPacket(&gsGuildMemberLogOn); Statement* pStmt = NULL; // 디비에 업데이트 한다. BEGIN_DB { pStmt = g_pDatabaseManager->getConnection("DARKEDEN")->createStatement(); pStmt->executeQuery("UPDATE GuildMember SET LogOn = 0 WHERE Name = '%s'", pVampire->getName().c_str()); } END_DB(pStmt) } else filelog("GuildMissing.log", "[NoSuchGuild] GuildID : %d, Name : %s\n", (int)pVampire->getGuildID(), pVampire->getName().c_str()); }