// 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;
}
Exemple #2
0
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
}