Exemple #1
0
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
}
Exemple #3
0
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());
	}
Exemple #6
0
//----------------------------------------------------------------------
// 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
}
Exemple #7
0
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
}
Exemple #8
0
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
}
Exemple #10
0
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
}
Exemple #12
0
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;
}
Exemple #13
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;
}
Exemple #14
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);
	}
Exemple #17
0
//--------------------------------------------------------------------------------
//
// 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
}
Exemple #18
0
//---------------------------------------------------------------------------
// 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
}
Exemple #22
0
//////////////////////////////////////////////////////////////////////////////
// 슬레이어 오브젝트 핸들러
//////////////////////////////////////////////////////////////////////////////
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);
				}
			}
Exemple #24
0
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);
	}
Exemple #25
0
//////////////////////////////////////////////////////////////////////////////
// 슬레이어 오브젝트 핸들러
//////////////////////////////////////////////////////////////////////////////
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());
			}