#pragma once //================================================================================================== /// RoomInterface Ŭ·¡½º /** @author Kim Min Wook < taiyo@webzen.com > @since 2005. 9. 20 @remark - @note - @history - @usage - */ //================================================================================================== #include #include "ZoneInterface.h" enum eROOMSTATE_TYPE { eROOMSTATE_NONE, //< ¾Æ¹«°Íµµ ¾Æ´Ñ »óÅ eROOMSTATE_READY, //< Áغñ»óÅ eROOMSTATE_GENERNAL, //< ÀϹÝÀûÀλóÅ eROOMSTATE_DESTROY, //< ÆÄ±«µÈ ¹æ }; class Party; struct MSG_AG_ZONE_CAN_CREATE_ROOM_ACK; typedef util::SolarHashTable::iterator PARTY_ITERATOR; //================================================================================================== // class RoomInterface : public ZoneInterface { friend class ZoneManager; //< CanJoin() public: enum { MAX_DESTROY_TIMEOUT_TIME = 10 * 60 * 1000, MAX_RELAY_TIMEOUT_TIME = 10 * 60 * 1000, }; RoomInterface(void); virtual ~RoomInterface(void); inline User* GetMaster() { return m_pMasterUser; } inline eZONEPUBLIC GetZonePublic() const { return (eZONEPUBLIC)m_byRoomPublic; } inline TCHAR* GetRoomTitle() { return m_pszRoomTitle; } inline TCHAR* GetRoomPWD() { return m_pszRoomPWD; } inline eROOMSTATE_TYPE GetRoomState() const { return m_RoomState; } inline void SetRoomState(eROOMSTATE_TYPE sts) { m_RoomState = sts; } virtual BOOL IsRoomType() const { return TRUE; } inline void SetLimitMaxUserNum(BYTE num) { m_MaxLimitUserNum = num; } inline BYTE GetLimitMaxUserNum() const { return m_MaxLimitUserNum; } virtual BOOL RecommendLevel(LEVELTYPE level) { __UNUSED(level); return FALSE; } //virtual MAPCODE GetMapCode() { return m_MapCode; } RC::eROOM_RESULT IsRecommendRoom(User* pUser); void VestUserWithMaster(User* pExpectedMaster); User* GetNextPriorityMaster(RoomInterface* pRoom, DWORD curMasterKey, eROOM_SPECIAL_TYPE* OUT pRoomSpecialTypeByUser); User* ChangeSpecialType(BOOLEAN isEnterEvent, User* pMaster); // Æò±Õ ·¹º§, ½Â·ü LEVELTYPE GetAvgLevel(); void GetCHuntingScore(BYTE& byAvgWinPercent, DWORD& dwTotCount); protected: void Create(User* pUser, KEYTYPE key, MAPCODE MapCode, eZONEPUBLIC ePublic, TCHAR* pszRoomTitle, TCHAR* pszRoomPWD, BASE_ROOMINFO& IN baseRoomInfo, ServerSession* pServerSession); RC::eROOM_RESULT CanCreate(User* pUser, MAPCODE MapCode, eZONETYPE eZoneType, eZONEPUBLIC ePublic, BASE_ROOMINFO& IN baseRoomInfo, BOOL CheckOpenTime = TRUE); //{__NA1279_1281_090209_TIMELINE_QUEST_BASED_MISSION__ // Setting by ZoneManager void ChangePolicy(PolicymentForRoom::POLICY_T newPolicySet); virtual RC::eROOM_RESULT MigratePortalUserFirstEnter(KEYTYPE key, const RoomArgumentForRoomSetup& rRoomArgument, User* pUser, ServerSession* pServerSession); //} public: virtual RC::eROOM_RESULT _CanJoinAll(User* pUser, eZONEPUBLIC RoomPublic, TCHAR* pszRoomPWD); #if defined(__NA_000000_20070528_TAIWAN_GUILD_PVP) && defined(__TW_0_20080521_GUILD_PVP_BUG_FIX) // ´ë¸¸ ±æµåÀü üũ´Â ÇåÆÃ·ë¿¡¸¸ ¼ÓÇÏÁö ¾ÊÀ»¼ö ÀÖ°í, ·ëÀÇ Å¸ÀÔüũ´Â ·ëÁ¤º¸ ±¸Á¶Ã¼¸¦ °¡Áø thisŬ·¡½º¿¡¼­ üũ RC::eROOM_RESULT CanJoinGuildPVP(User* pUser); BOOL IsSpecialType(eROOM_SPECIAL_TYPE SpecialType) { return m_RoomInfo.IsSpecialType(SpecialType); } #endif//__NA_000000_20070528_TAIWAN_GUILD_PVP BOOL ValidCharClass(eCHAR_TYPE type); BOOL ValidLevel(LEVELTYPE LV); BOOL ValidJoinMap(User* pUser); virtual BOOL CanShowAtRoomList(User* pUser, eZONEPUBLIC RoomPublic, TCHAR* pszRoomPWD); virtual RC::eROOM_RESULT Migrate(KEYTYPE key, RoomInterface* pPreviousRoom, ServerSession* pServerSession); void RelayUser(RoomInterface* pPreviousRoom); virtual BOOL Process(); virtual void On_create(); virtual void On_destroy(); virtual void On_readyuser(User* pUser); virtual void On_enteruser(User* pUser); virtual void On_leaveuser(User* pUser); //void SetMapCode(MAPCODE code); inline void SetZonePublic(eZONEPUBLIC pub); inline void SetRoomPWD(TCHAR* pw); inline void SetRoomInfo(const BASE_ROOMINFO* pRoomInfo); inline void SetMaster(User* pUser); inline void SetRoomTitle(const TCHAR* title); inline BASE_ROOMINFO* GetRoomInfo() { return &m_RoomInfo; } // (WAVERIX) (NOTE) Çϱâ interface´Â ÀڷᱸÁ¶ º¯°æ ÀÌÈÄ ¼öÁ¤Çϱâ·Î ÇÑ´Ù. inline virtual DWORD GetCurUserNum() { return ZoneInterface::GetUserNum() + m_RelayUserHash.GetDataNum(); } inline util::SolarHashTable& GetRelayHash() { return m_RelayUserHash; } inline User* FindRelayUser(DWORD PlayerKey) { return m_RelayUserHash.GetData(PlayerKey); } inline void RemoveRelayUser(DWORD playerKey) { m_RelayUserHash.Remove(playerKey); } inline void AddRelayUser(User* pUser, DWORD playerKey) { m_RelayUserHash.Add(pUser, playerKey); } //__NA000000_090622_MOB_ABILITY_CONTROL_CHANGE__ inline BYTE GetNumberOfExpectedPlayers() const { return m_NumberOfExpectedPlayers; } inline void SetNumberOfExpectedPlayers(BYTE number_of_players); bool ExceptionProcessByLobbyMember(const MSG_AG_ZONE_CAN_CREATE_ROOM_ACK* check_msg, User* request_user); PolicymentForRoom RoomPolicyment; // Property private: virtual BOOL CheckLimitUser(User* pUser); ////////////////////////////////////////////////////////////////////////// // Fields eROOMSTATE_TYPE m_RoomState; util::Timer m_DestroyTimeout; util::Timer m_MasterEnterTimeout; util::SolarHashTable m_RelayUserHash; // ¹æÁ¤º¸ User* m_pMasterUser; BYTE m_NumberOfExpectedPlayers; //__NA000000_090622_MOB_ABILITY_CONTROL_CHANGE__ BYTE m_byRoomPublic; //< eZONEPUBLIC TCHAR m_pszRoomTitle[MAX_ROOMTITLE_LENGTH + 1]; //< ¾ÈÀüÇÑ ¹®ÀÚ¿­ 󸮸¦ À§ÇØ +1 TCHAR m_pszRoomPWD[MAX_ROOMPASSWORD_LENGTH + 1]; //< ¾ÈÀüÇÑ ¹®ÀÚ¿­ 󸮸¦ À§ÇØ +1 BYTE m_MaxLimitUserNum; BASE_ROOMINFO m_RoomInfo; //< »ý¼ºÇÒ ¹æ Á¤º¸ }; // //================================================================================================== // inline void RoomInterface::SetNumberOfExpectedPlayers(BYTE number_of_players) { //__NA000000_090622_MOB_ABILITY_CONTROL_CHANGE__ m_NumberOfExpectedPlayers = number_of_players; } inline void RoomInterface::SetZonePublic(eZONEPUBLIC pub) { m_byRoomPublic = static_cast(pub); } inline void RoomInterface::SetRoomPWD(TCHAR* pw) { if(pw == 0) return; _tcsncpy(m_pszRoomPWD, pw, _countof(m_pszRoomPWD)); m_pszRoomPWD[_countof(m_pszRoomPWD) - 1] = '\0'; } inline void RoomInterface::SetRoomInfo(const BASE_ROOMINFO* pRoomInfo) { m_RoomInfo = *pRoomInfo; } inline void RoomInterface::SetMaster(User* pUser) { m_pMasterUser = pUser; } inline void RoomInterface::SetRoomTitle(const TCHAR* title) { _tcsncpy(m_pszRoomTitle, title, _countof(m_pszRoomTitle)); m_pszRoomTitle[_countof(m_pszRoomTitle) - 1] = '\0'; } //================================================================================================== // template class RoomMigrater { SRC_ROOM* m_SrcRoom; TARGET_ROOM* m_pTargetRoom; public: RoomMigrater(SRC_ROOM* pSrc, TARGET_ROOM* pTarget) : m_SrcRoom(pSrc), m_pTargetRoom(pTarget) {} ~RoomMigrater() {} void operator()(User* pUser) { pUser->BeginTransaction((eBEHAVE_TRANSACTION)Transaction); m_SrcRoom->LeaveUser(pUser, eSEND_SYN, m_pTargetRoom->GetType(), m_pTargetRoom->GetLinkedServerIndex()); // ÇåÆÃ۸¦ ÀúÀåÇØµÒ!!!! pUser->SetTRRoomKey(m_pTargetRoom->GetKey()); DISPMSG("[U:%s]room(%u)_Leave_Syn\n", pUser->GetUserID(), m_pTargetRoom->GetKey()); } }; //_NA_20110630_BATTLE_ZONE_RENEWAL template class RoomMigraterByParty { TARGET_ROOM* target_room_; public: RoomMigraterByParty(TARGET_ROOM* target_room) : target_room_(target_room){} ~RoomMigraterByParty(){} void operator()(_PARTY_MEMBER_INFO* member_info) { User* user = UserManager::Instance()->GetUserByObjKey(member_info->m_dwMemberKey); if (user == NULL) { SUNLOG(eCRITICAL_LOG, __FUNCTION__" : Not found user : %d", member_info->m_dwMemberKey); return; } WORD party_key = user->GetPartyState().GetPartyKey(); DWORD master_key = AgentPartyManager::Instance()->GetMasterKey(party_key); if (user->GetPlayerKey() == master_key) { return; } ZoneInterface* current_zone_interface = g_ZoneManager.FindZone(user->GetZoneKey()); if (current_zone_interface == NULL) { SUNLOG(eCRITICAL_LOG, __FUNCTION__ " : Not found zone : %d", user->GetUserGUID()); return; } user->BeginTransaction((eBEHAVE_TRANSACTION)Transaction); current_zone_interface->LeaveUser(user, eSEND_SYN, target_room_->GetType(), target_room_->GetLinkedServerIndex()); user->SetTRRoomKey(target_room_->GetKey()); } }; //================================================================================================== // struct ChangeRoomName : public std::unary_function { MSG_CG_ZONE_EX_LOBBY_NAME_CHANGE_ACK m_SendData; explicit ChangeRoomName(const char* pszRoomName) { BOOST_STATIC_ASSERT(_countof(m_SendData.m_pszRoomTitle) == MAX_ROOMTITLE_LENGTH); strncpy(m_SendData.m_pszRoomTitle, pszRoomName, _countof(m_SendData.m_pszRoomTitle)); m_SendData.m_pszRoomTitle[_countof(m_SendData.m_pszRoomTitle) - 1] = '\0'; } inline void operator()(User* pUser) { pUser->SendPacket(&m_SendData, sizeof(m_SendData)); } };