// function CChatRoom::Join // Joins a user to this chatroom bool CChatRoom::Join(int user) { if ( !m_bActive ) { CLog::Error("Could not join chat room - Chat not intialized", __FUNCTION__); return false; } Pthread_mutex_lock(&CUser::m_UserMutex, __FUNCTION__); CUser* currUser = CUser::GetUser(user); if ( currUser == 0 ) { CLog::Error("User id %d not found", __FUNCTION__, user); Pthread_mutex_unlock(&CUser::m_UserMutex, __FUNCTION__); return false; } Pthread_mutex_lock(&m_InsideUsersMutex, __FUNCTION__); // the only time this is a linear search is when someone logs in and logs out list<int>::iterator iter = m_UsersInside.begin(); while ( iter != m_UsersInside.end() ) { if ( *iter == user ) { // if user is already in the chat room, refuse entry CLog::Record("Failed to login to chat room %s - %d already in there", GetName().c_str(), *iter ); Pthread_mutex_unlock(&m_InsideUsersMutex, __FUNCTION__); Pthread_mutex_unlock(&CUser::m_UserMutex, __FUNCTION__); return false; } iter++; } /* // size_t BufferSize = 9 + (MAXNAME+7)*users, namelen; if ( m_sName.length() >= MAXCHATNAMELEN ) namelen = MAXCHATNAMELEN; else namelen = m_sName.length()+1; // BufferSize += namelen; */ // char* LoggedInBuffer = new char[BufferSize]; size_t users = m_UsersInside.size(); char LoggedInBuffer[9]; char* temp = LoggedInBuffer; *temp = PACK_JOINCHAT; temp++; *(int*)temp = this->m_ChatID; temp += 4; *(int*)temp = (int)users; temp += 4; currUser->SendTo(LoggedInBuffer, 9); vector<int> toKick; char CurrUserData[MAXNAME+MAXCLAN+9]; temp = CurrUserData; *temp = PACK_USERENTERCHAT; temp++; *(int*)temp = this->m_ChatID; temp += sizeof(int); *(int*)temp = currUser->GetId(); temp += sizeof(int); strncpy(temp, currUser->GetName(), MAXNAME); temp += MAXNAME; strncpy(temp, currUser->GetClan(), MAXCLAN); for ( iter = m_UsersInside.begin(); iter != m_UsersInside.end(); iter++ ) { char UserData[MAXNAME+MAXCLAN+4]; temp = UserData; CUser* currUser2 = CUser::GetUser(*iter); // this really shouldnt happen either, we checked for it earlier if ( *iter == user ) //|| currUser == 0 ) { Pthread_mutex_unlock(&CUser::m_UserMutex, __FUNCTION__); Pthread_mutex_unlock(&m_InsideUsersMutex, __FUNCTION__); return false; } // this shouldn't happen, but if we come across a user with a null pointer, we kick him/her from the room if ( currUser2 == 0 ) { //**** Send a boot message to everyone in the chatroom toKick.push_back(*iter); m_UsersInside.erase(iter); continue; } CLog::Record("Sending PACK_USERENTERCHAT to %s", currUser2->GetName()); currUser2->SendTo(CurrUserData, MAXNAME+MAXCLAN+9); *(int*)temp = currUser2->GetId(); temp += sizeof(int); strncpy(temp, currUser2->GetName(), MAXNAME); temp += MAXNAME; // in here goes the clan strncpy(temp, currUser2->GetClan(), MAXCLAN); temp += MAXCLAN; currUser->SendTo(UserData, MAXNAME+MAXCLAN+4); } m_UsersInside.push_back(user); Pthread_mutex_unlock(&m_InsideUsersMutex, __FUNCTION__); // currUser->SendTo(LoggedInBuffer, BufferSize); Pthread_mutex_unlock(&CUser::m_UserMutex, __FUNCTION__); if ( toKick.size() > 0 ) Kicked(toKick); // delete[] LoggedInBuffer; // LoggedInBuffer = 0; return true; }
void CParty::DoUsePartySkill( u_long uPartyId, u_long uLeaderid, int nSkill ) { #ifdef __WORLDSERVER CUser* pMember = NULL; int i; if( IsLeader( uLeaderid ) && m_nKindTroup == 1 ) { ItemProp* pItemProp = prj.GetPartySkill( nSkill ); if( pItemProp ) { #ifndef __PARTYDEBUG if( int( GetLevel() - pItemProp->dwReqDisLV ) >= 0 ) #endif // __PARTYDEBUG { #ifndef __PARTYDEBUG #if __VER >= 12 // __JHMA_VER12_1 //12차 극단유료아이템 CUser *pLeadertmp = g_UserMng.GetUserByPlayerID( m_aMember[0].m_uPlayerId ); // 리더의 포인터 if( IsValidObj( pLeadertmp ) == FALSE ) return; int nHasCashSkill = 0,nFPoint = 0; if( pLeadertmp->HasBuff( BUFF_ITEM2, II_SYS_SYS_SCR_PARTYSKILLUP01 ) || pLeadertmp->HasBuff( BUFF_ITEM2, II_SYS_SYS_SCR_PARTYSKILLUP02 ) || pLeadertmp->HasBuff( BUFF_ITEM2, II_SYS_SYS_SCR_PARTYSKILLUP01_01 ) ) { if( nSkill == ST_LINKATTACK || nSkill == ST_FORTUNECIRCLE || nSkill == ST_STRETCHING || nSkill == ST_GIFTBOX ) nHasCashSkill = 1; } DWORD dwSkillTime = pItemProp->dwSkillTime; int nRemovePoint = pItemProp->dwExp; nFPoint = int( GetPoint() - pItemProp->dwExp); #if __VER >= 12 // __LORD // 군주의 극단 // 군주가 극단장 으로써 극단스킬 사용 시, // 지속시간 4배 증가(소모 포인트는 동일) if( CSLord::Instance()->IsLord( uLeaderid ) ) dwSkillTime *= 4; #endif // __LORD if( nFPoint >= 0 ) #else if( int( GetPoint() - pItemProp->dwExp) >= 0 ) #endif // //12차 극단유료아이템 #endif // __PARTYDEBUG { switch( nSkill ) { case ST_CALL: { g_DPCoreClient.SendRemovePartyPoint( uPartyId, pItemProp->dwExp ); CUser *pLeader = g_UserMng.GetUserByPlayerID( m_aMember[0].m_uPlayerId ); // 리더의 포인터 if( IsValidObj( pLeader ) == FALSE ) break; // 단장 중심으로 모여달라는 표시 for( i = 0; i < m_nSizeofMember; i ++ ) // 단장(0)에게는 보낼필요 없다. { pMember = g_UserMng.GetUserByPlayerID( m_aMember[i].m_uPlayerId ); // 단장 어라운드 지역에 있는 사람에게만 보낸다 if( IsValidObj( (CObj*)pMember ) ) pMember->AddPartySkillCall( pLeader->GetPos() ); // 각 멤버들에게 단장이 좌표를 전송함. } } break; case ST_BLITZ: { CUser *pLeader = g_UserMng.GetUserByPlayerID( m_aMember[0].m_uPlayerId ); // 리더의 포인터 if( IsValidObj( pLeader ) == FALSE ) break; if( pLeader->m_idSetTarget != NULL_ID ) { CMover *pT = prj.GetMover( pLeader->m_idSetTarget ); if( pT && !pT->IsPlayer() ) { g_DPCoreClient.SendRemovePartyPoint( uPartyId, pItemProp->dwExp ); // 단장이 타겟으로 집중공격 표시 for( i = 0; i < m_nSizeofMember; i ++ ) { pMember = g_UserMng.GetUserByPlayerID( m_aMember[i].m_uPlayerId ); if( IsValidObj( (CObj*)pMember ) ) { if( m_nModeTime[PARTY_GIFTBOX_MODE] || m_nModeTime[PARTY_FORTUNECIRCLE_MODE] ) { pMember->AddPartySkillBlitz( pLeader->m_idSetTarget ); // 각 멤버들에게 단장타겟으로 잡은 무버의 아이디를 보냄. } else { if( pLeader->IsNearPC( pMember ) ) pMember->AddPartySkillBlitz( pLeader->m_idSetTarget ); // 각 멤버들에게 단장타겟으로 잡은 무버의 아이디를 보냄. } } } } else { pLeader->AddSendErrorParty( ERROR_NOTTARGET, ST_BLITZ ); } } else { pLeader->AddSendErrorParty( ERROR_NOTTARGET, ST_BLITZ ); // 타겟을 안잡았다. } } break; case ST_RETREAT: { g_DPCoreClient.SendRemovePartyPoint( uPartyId, pItemProp->dwExp ); // 후퇴 표시 CUser *pLeader = g_UserMng.GetUserByPlayerID( m_aMember[0].m_uPlayerId ); // 리더의 포인터 if( IsValidObj( pLeader ) == FALSE ) break; for( i = 0; i < m_nSizeofMember; i ++ ) { pMember = g_UserMng.GetUserByPlayerID( m_aMember[i].m_uPlayerId ); if( IsValidObj( (CObj*)pMember ) ) { if( m_nModeTime[PARTY_GIFTBOX_MODE] || m_nModeTime[PARTY_FORTUNECIRCLE_MODE] ) { pMember->AddHdr( pMember->GetId(), SNAPSHOTTYPE_PARTYSKILL_RETREAT ); } else { if( pLeader->IsNearPC( pMember ) ) pMember->AddHdr( pMember->GetId(), SNAPSHOTTYPE_PARTYSKILL_RETREAT ); } } } } break; case ST_SPHERECIRCLE: { // 크리티컬 확률 CUser *pLeader = g_UserMng.GetUserByPlayerID( m_aMember[0].m_uPlayerId ); // 리더의 포인터 if( IsValidObj( pLeader ) == FALSE ) break; if( pLeader->m_idSetTarget != NULL_ID ) { CMover * pT = prj.GetMover( pLeader->m_idSetTarget ); if( pT && !pT->IsPlayer() ) { g_DPCoreClient.SendRemovePartyPoint( uPartyId, pItemProp->dwExp ); for( i = 0; i < m_nSizeofMember; i ++ ) { pMember = g_UserMng.GetUserByPlayerID( m_aMember[i].m_uPlayerId ); if( IsValidObj( (CObj*)pMember ) ) { if( m_nModeTime[PARTY_GIFTBOX_MODE] || m_nModeTime[PARTY_FORTUNECIRCLE_MODE] ) { pMember->AddHdr( pLeader->m_idSetTarget, SNAPSHOTTYPE_PARTYSKILL_SPHERECIRCLE ); pMember->m_dwFlag |= MVRF_CRITICAL; } else { if( pLeader->IsNearPC( pMember ) ) { pMember->AddHdr( pLeader->m_idSetTarget, SNAPSHOTTYPE_PARTYSKILL_SPHERECIRCLE ); pMember->m_dwFlag |= MVRF_CRITICAL; } } } } } else { pLeader->AddSendErrorParty( ERROR_NOTTARGET, ST_SPHERECIRCLE ); // 타겟이 몬스터가 아니다 } } else { pLeader->AddSendErrorParty( ERROR_NOTTARGET, ST_SPHERECIRCLE ); // 타겟을 안잡았다. } // g_DPCoreClient.SendSetPartyExp( uLeaderid, m_nPoint ); } break; #if __VER >= 12 // __JHMA_VER12_1 //12차 극단유료아이템 case ST_LINKATTACK: { // 데미지 증가 g_DPCoreClient.SendUserPartySkill( uLeaderid, PARTY_LINKATTACK_MODE, dwSkillTime, nRemovePoint, nHasCashSkill ); } break; case ST_FORTUNECIRCLE: { // 유니크 아이템 발생확률 증가 g_DPCoreClient.SendUserPartySkill( uLeaderid, PARTY_FORTUNECIRCLE_MODE, dwSkillTime, nRemovePoint, nHasCashSkill ); } break; case ST_STRETCHING: { // 쉬는경우 회복속도 높여줌 g_DPCoreClient.SendUserPartySkill( uLeaderid, PARTY_STRETCHING_MODE, dwSkillTime, nRemovePoint, nHasCashSkill ); } break; case ST_GIFTBOX: { // 아이템 양이 두배 g_DPCoreClient.SendUserPartySkill( uLeaderid, PARTY_GIFTBOX_MODE, dwSkillTime, nRemovePoint, nHasCashSkill ); } break; #else //12차 극단유료아이템 case ST_LINKATTACK: { // 데미지 증가 g_DPCoreClient.SendUserPartySkill( uLeaderid, PARTY_LINKATTACK_MODE, dwSkillTime, nRemovePoint ); } break; case ST_FORTUNECIRCLE: { // 유니크 아이템 발생확률 증가 g_DPCoreClient.SendUserPartySkill( uLeaderid, PARTY_FORTUNECIRCLE_MODE, dwSkillTime, nRemovePoint ); } break; case ST_STRETCHING: { // 쉬는경우 회복속도 높여줌 g_DPCoreClient.SendUserPartySkill( uLeaderid, PARTY_STRETCHING_MODE, dwSkillTime, nRemovePoint ); } break; case ST_GIFTBOX: { // 아이템 양이 두배 g_DPCoreClient.SendUserPartySkill( uLeaderid, PARTY_GIFTBOX_MODE, dwSkillTime, nRemovePoint ); } break; #endif // //12차 극단유료아이템 default: break; } } #ifndef __PARTYDEBUG else { CUser *pLeader = g_UserMng.GetUserByPlayerID( m_aMember[0].m_uPlayerId ); // 리더의 포인터 if( IsValidObj( pLeader ) ) { pLeader->AddSendErrorParty( ERROR_NOTPARTYPOINT ); } //포인트가 모자라 스킬을사용할수 없습니다. } #endif // __PARTYDEBUG } #ifndef __PARTYDEBUG else { CUser *pLeader = g_UserMng.GetUserByPlayerID( m_aMember[0].m_uPlayerId ); // 리더의 포인터 if( IsValidObj( pLeader ) ) { pLeader->AddSendErrorParty( ERROR_NOTPARTYSKILL ); } //이 스킬은 배우지를 못했습니다. } #endif // __PARTYDEBUG } } else { // 리더가 아니거나 순회극단이 아닌경우 } #endif // __WORLDSERVER }