void CPartyMng::AddConnection( CPlayer* pPlayer ) { CParty* pParty; CMclAutoLock Lock( m_AddRemoveLock ); pParty = GetParty( pPlayer->m_uPartyId ); if( pParty ) { int i = pParty->FindMember( pPlayer->uKey ); if( i < 0 ) { pPlayer->m_uPartyId = 0; return; } pParty->m_aMember[i].m_bRemove = FALSE; pParty->m_nReferens--; BEFORESENDDUAL( ar, PACKETTYPE_ADDPLAYERPARTY, DPID_UNKNOWN, DPID_UNKNOWN ); ar << pPlayer->m_uPartyId << pPlayer->uKey; SEND( ar, &g_dpCoreSrvr, DPID_ALLPLAYERS ); } else pPlayer->m_uPartyId = 0; }
// 극단 해체 // 해체는 사람이 부족하여 자동으로 해체 // 단독적으로 해체할수 없음 BOOL CPartyMng::DeleteParty( u_long uPartyId ) { CParty* pParty = GetParty( uPartyId ); if( pParty ) { if( pParty->m_idDuelParty ) // 극단듀얼중일때 극단이 해체되었으면 { CParty *pDstParty = GetParty( pParty->m_idDuelParty ); // 상대 파티원들에게도 this파티가 해체되어 듀얼이해제됐다는걸 알림. if( pDstParty ) { pDstParty->DoDuelPartyCancel( pParty ); } else { Error( "CPartyMng::DeleteParty : 상대파티를 찾을 수 없음 %d", pParty->m_idDuelParty ); } #ifdef __WORLDSERVER g_DPCoreClient.SendSetPartyDuel( pParty->m_uPartyId, pParty->m_idDuelParty, FALSE ); #endif // __WORLDSERVER pParty->DoDuelPartyCancel( pDstParty ); // this파티원들에게도 듀얼해제됐다는걸 알림. } #ifdef __WORLDSERVER #if __VER >= 14 // __INSTANCE_DUNGEON CInstanceDungeonParty::GetInstance()->DestroyAllDungeonByDungeonID( uPartyId ); #endif // __INSTANCE_DUNGEON #endif // __WORLDSERVER safe_delete( pParty ); m_2PartyPtr.erase( uPartyId ); return TRUE; } return FALSE; }
void CPartyQuestProcessor::SetPartyQuest( int nQuestId, int nState, int ns, int nf, u_long idParty, OBJID objidWormon ) { if( nQuestId >= MAX_PARTY_QUEST ) { Error( "" ); return; } PARTYQUESTPROP* pProp = prj.GetPartyQuestProp( nQuestId ); if( !pProp ) { Error( "" ); return; } TRACE( "SET_PARTY_QUEST, %d, %d, %d\n", nQuestId, idParty, objidWormon ); PPARTYQUESTELEM pElem = &m_pElem[nQuestId]; pElem->nId = nQuestId; pElem->nState = nState; pElem->idParty = idParty; pElem->dwEndTime = GetTickCount() + MIN( 60 ); pElem->nProcess = PQP_WORMON; pElem->ns = ns; pElem->nf = nf; pElem->objidWormon = objidWormon; pElem->nCount = 0; // 유저에게 공략시간을 넘겨준다... SendQuestLimitTime( PQP_WORMON, MIN( 60 ), idParty ); // 파티퀘스트시작시 정보를 파일에 기록한다. CString strFileName = "StartPartyQuestInfo.txt"; CString strQuestInfo; CString strMemberName; CString strDateTime; CTime time = CTime::GetCurrentTime(); strDateTime.Format( "DATE : %d%.2d%.2d\nTIME : %d::%d::%d\n", time.GetYear(), time.GetMonth(), time.GetDay(), time.GetHour(), time.GetMinute(), time.GetSecond() ); strQuestInfo.Format( "QUEST ID = %d, PARTY ID = %d, WORMON ID = %d\n", nQuestId, idParty, objidWormon ); CParty* pParty = g_PartyMng.GetParty( idParty ); if( pParty ) { int i; for( i = 0 ; i < pParty->GetSizeofMember() ; ++i ) { CUser* pUsertmp = (CUser *)prj.GetUserByID( pParty->GetPlayerId( i ) ); if( IsValidObj( pUsertmp ) ) { strMemberName += pUsertmp->GetName(); strMemberName += "\n"; } } } FILEOUT( strFileName, "%s%s%s\n", strDateTime, strQuestInfo, strMemberName ); //////////////////////////////////////////////////////////////////////////////////////////// }
// Party Chat bool CWorldServer::pakPartyChat( CPlayer* thisclient, CPacket* P ) { CParty* party = thisclient->Party->party; if(party==NULL) return true; BEGINPACKET( pak, 0x786 ); ADDWORD ( pak, thisclient->clientid ); ADDSTRING ( pak, P->Buffer ); ADDBYTE ( pak, 0 ); party->SendToMembers( &pak ); return true; }
// Change Party Options bool CWorldServer::pakPartyOption( CPlayer* thisclient, CPacket* P ) { if(!thisclient->Party->IsMaster) return true; CParty* party = thisclient->Party->party; if(party==NULL) return true; party->Option = GETBYTE((*P),0); BEGINPACKET( pak, 0x7d7 ); ADDBYTE ( pak, party->Option ); ADDBYTE ( pak, 0x00 ); party->SendToMembers( &pak ); return true; }
void CPartyQuestProcessor::SendQuestLimitTime( int nState, DWORD dwTime, u_long idParty ) { CParty* pParty = g_PartyMng.GetParty( idParty ); if( pParty ) { int i; for( i = 0 ; i < pParty->GetSizeofMember() ; ++i ) { CUser* pUsertmp = (CUser *)prj.GetUserByID( pParty->GetPlayerId( i ) ); if( IsValidObj( pUsertmp ) ) { pUsertmp->AddQuestTextTime( 1, nState, dwTime ); } } } }
void CAlliance::dissolveAlliance(void) { //first kick out the third party if it exsists if (this->partyCount() == 3) this->removeParty(this->partyList.at(2)); //kick out the second party this->removeParty(this->partyList.at(1)); CParty* party = this->partyList.at(0); this->partyList.clear(); party->m_PAlliance = NULL; party->ReloadParty(); delete this; }
void GetPartyList(classUSER* user){ CustomAvatarData* data = CustomAvatarData::Get(user); clock_t dt = clock() - data->mPartyListUpdate; if(dt < 10000) return; data->mPartyListUpdate = clock(); classPACKET* cpak = Packet_AllocNLock(); if(!cpak) return; CPacket* pak = (CPacket*)cpak; pak->CreateNew(PAK_PARTYLIST); pak->Add<byte>(PAK_PARTY_CLEAR); user->SendPacket(cpak); int parties = g_pPartyBUFF->m_iUsedSlot; int usrlevel = user->Get_LEVEL(); for(int i = 0, found = 0; i < 0x2000, found < parties; ++i){ CParty* party = g_pPartyBUFF->GetData(i); if(!party) continue; ++found; if(gCustomPartyData[i].mPrivate == 1) continue; int average = party->GetAverageLEV(); int partylv = party->GetPartyLEV(); if(!user->Check_PartyJoinLEVEL(usrlevel, average, partylv)) continue; classUSER* owner = party->GetPartyOWNER(); if(!owner) continue; pak->CreateNew(PAK_PARTYLIST); pak->Add<unsigned char>(PAK_PARTY_ITEM); pak->Add<short>( partylv); pak->Add<short>( owner->m_nZoneNO); pak->Add<int>(average); pak->Add<int>(party->GetMemberCNT()); pak->AddString(owner->Get_NAME()); user->SendPacket(cpak); } Packet_ReleaseNUnlock(cpak); }
void SetPartyMode(CPacket* pak, classUSER* user){ unsigned char isPrivate = pak->Get<unsigned char>(1); CParty* party = user->GetPARTY(); if(!party) return; int idx = IDXByParty(party); if(idx < 0 || idx > 0x2000 || !user->Quest_IsPartyLEADER()) return; gCustomPartyData[idx].mPrivate = isPrivate; classPACKET* cpak = Packet_AllocNLock(); if(!cpak) return; CPacket* npak = (CPacket*)cpak; npak->CreateNew(PAK_PARTYLIST); npak->Add<unsigned char>(PAK_PARTY_MODE); npak->Add<unsigned char>(isPrivate); party->SendToPartyMembers(cpak); Packet_ReleaseNUnlock(cpak); }
void CPartyMng::Serialize( CAr & ar ) { #ifndef __WORLDSERVER m_AddRemoveLock.Enter( theLineFile ); // lock1 #endif // __WORLDSERVER if( ar.IsStoring() ) { ar << m_id; int nCount = 0; u_long uOffset = ar.GetOffset(); ar << nCount; for( C2PartyPtr::iterator i = m_2PartyPtr.begin(); i != m_2PartyPtr.end(); ++i ) { CParty* pParty = (CParty*)i->second; pParty->Serialize( ar ); nCount++; } int nBufSize1; LPBYTE lpBuf1 = ar.GetBuffer( &nBufSize1 ); *(UNALIGNED int*)( lpBuf1 + uOffset ) = nCount; } else { int nCount; ar >> m_id; ar >> nCount; for( int i = 0 ; i < nCount ; i++ ) { CParty* pParty = new CParty; // pParty->Lock(); pParty->Serialize( ar ); m_2PartyPtr.insert( C2PartyPtr::value_type( pParty->m_uPartyId, pParty ) ); // pParty->Unlock(); } } #ifndef __WORLDSERVER m_AddRemoveLock.Leave( theLineFile ); // unlock1 #endif // __WORLDSERVER }
// 극단 생성 // uLeaderPlayerId : 단장, uPartyId : 1번째 단원 // 극단를 생설할때는 2명으로 생성함( 혼자서는 극단를 생성할수 없음 ) u_long CPartyMng::NewParty( u_long uLeaderId, LONG nLeaderLevel, LONG nLeaderJob, BYTE nLeaderSex, LPSTR szLeaderName, u_long uMemberId, LONG nMemberLevel, LONG nMemberJob, BYTE nMemberSex, LPSTR szMembername, u_long uPartyId ) { // locked if( 0 == uPartyId ) { m_id++; } else { m_id = uPartyId; } if( NULL == GetParty( m_id ) ) // NULL 이면 극단이 없으므로 만들어야 한다 { CParty* pParty = new CParty; // pParty->Lock(); pParty->SetPartyId( m_id ); #if __VER >= 11 // __SYS_PLAYER_DATA if( TRUE == pParty->NewMember( uLeaderId ) && TRUE == pParty->NewMember( uMemberId ) ) #else // __SYS_PLAYER_DATA if( TRUE == pParty->NewMember( uLeaderId, nLeaderLevel, nLeaderJob, nLeaderSex, szLeaderName ) && TRUE == pParty->NewMember( uMemberId, nMemberLevel, nMemberJob, nMemberSex, szMembername ) ) #endif // __SYS_PLAYER_DATA { // m_2Party.SetAt( m_id, pParty ); m_2PartyPtr.insert( C2PartyPtr::value_type( m_id, pParty ) ); pParty->m_nGetItemPlayerId = pParty->m_aMember[0].m_uPlayerId; // pParty->Unlock(); return m_id; } else // 극단에 소속되어 있다 { // pParty->Unlock(); safe_delete( pParty ); } } return 0; }
void CPartyMng::PartyMapInfo( ) { const float PARTY_MAP_AROUND = 32.0f * 32.0f; // m_nVisibilityRange에 영향을 받는다. if( ++m_nSecCount < PARTY_MAP_SEC ) return; m_nSecCount = 0; D3DXVECTOR3 vPosBuf; float fDist; for( C2PartyPtr::iterator i = m_2PartyPtr.begin(); i != m_2PartyPtr.end(); ++i ) { CParty* pParty = (CParty*)i->second; for( int j = 0 ; j < pParty->GetSizeofMember() ; ++j ) { CMover* pMover = prj.GetUserByID( pParty->GetPlayerId( j ) ); if( !IsValidObj( pMover ) ) continue; vPosBuf = pMover->GetPos() - pParty->GetPos( j ); fDist = D3DXVec3LengthSq( &vPosBuf ); if( 0.0f < fDist ) { pParty->SetPos( j, pMover->GetPos() ); CMover* pSendMover; for( int k = 0 ; k < pParty->GetSizeofMember() ; ++k ) { if( k == j ) continue; pSendMover = prj.GetUserByID( pParty->GetPlayerId( k ) ); if( !IsValidObj( pSendMover ) ) continue; vPosBuf = pSendMover->GetPos() - pMover->GetPos(); fDist = D3DXVec3LengthSq( &vPosBuf ); if( fDist > PARTY_MAP_AROUND ) ((CUser*)pSendMover)->AddPartyMapInfo( j, pMover->GetPos() ); } } } } }
// Party Actions [invite/leave/kick] bool CWorldServer::pakPartyActions( CPlayer* thisclient, CPacket* P ) { unsigned int action = GETBYTE((*P),0); CMap* map = MapList.Index[thisclient->Position->Map]; switch(action) { case 0x00://Invita a new party case 0x01://invite a existent party { UINT clientid = GETWORD((*P),1); if(thisclient->Party->party!=NULL) { //LMA: Refreshing Capacity if needed thisclient->Party->party->RefreshMax(); if(thisclient->Party->party->Members.size()>=thisclient->Party->party->Capacity) { SendSysMsg( thisclient, "Party is full" ); return true; } } CPlayer* otherclient = map->GetPlayerInMap( clientid );// have to be in same map if(otherclient==NULL) { BEGINPACKET( pak, 0x7d1 ); ADDBYTE ( pak, 0x00 );//No encontro el ID ADDWORD ( pak, clientid ); ADDBYTE ( pak, 0x00 ); thisclient->client->SendPacket( &pak ); return true; } if(otherclient->Party->party!=NULL) { BEGINPACKET( pak, 0x7d1 ); ADDBYTE ( pak, 0x01 );//No puede ser solicitado (ya tiene party) ADDWORD ( pak, clientid ); ADDBYTE ( pak, 0x00 ); thisclient->client->SendPacket( &pak ); return true; } if(abs(otherclient->Stats->Level-thisclient->Stats->Level)>(Config.Partygap+1)) { BEGINPACKET( pak, 0x7d1 ); ADDBYTE ( pak, 0x07 );//Level inapropiado ADDWORD ( pak, clientid ); ADDBYTE ( pak, 0x00 ); thisclient->client->SendPacket( &pak ); return true; } BEGINPACKET( pak, 0x7d0 ); ADDBYTE ( pak, action ); ADDWORD ( pak, thisclient->clientid ); ADDBYTE ( pak, 0x00 ); otherclient->client->SendPacket( &pak ); } break; case 0x02://Leave Party { if(thisclient->Party->party==NULL) return true; CParty* party = thisclient->Party->party; BEGINPACKET( pak, 0x7d2 ); ADDWORD ( pak, 0xff00 ); ADDDWORD ( pak, thisclient->CharInfo->charid ); bool pflag = false; if(!party->RemovePlayer( thisclient )) //if this player is not in this party return true; if(party->Members.size()>1) { for(UINT i=0;i<party->Members.size();i++) { CPlayer* thismember = party->Members.at(i); if(!pflag) { ADDDWORD( pak, thismember->CharInfo->charid ); if(thisclient->Party->IsMaster) thismember->Party->IsMaster = true; pflag = true; } thismember->client->SendPacket( &pak ); } } else { for(UINT i=0;i<party->Members.size();i++) { CPlayer* thismember = party->Members.at(i); BEGINPACKET( pak, 0x7d1 ); ADDBYTE ( pak, 0x05 ); ADDWORD ( pak, 0x0000 ); ADDWORD ( pak, 0x0000 ); thismember->client->SendPacket( &pak ); thismember->Party->party = NULL; thismember->Party->IsMaster = true; } RemoveParty( party ); delete party; } } break; case 0x03: //Tomiz: Give leader New Way { if(thisclient->Party->party==NULL) return true; unsigned int clientid = GETWORD((*P),1); if ( !thisclient->Party->IsMaster || clientid == thisclient->clientid ) return true; CPlayer* otherclient = GetClientByID( clientid ); if(otherclient==NULL) return true; BEGINPACKET(pak, 0x7d1); ADDBYTE(pak, 8); ADDWORD(pak, otherclient->clientid); ADDWORD(pak, 0); otherclient->Party->IsMaster = true; thisclient->Party->IsMaster = false; thisclient->Party->party->SendToMembers( &pak ); } break; case 0x81: //Kick from party { unsigned int charid = GETDWORD((*P),1); if(thisclient->Party->party==NULL) return true; if(!thisclient->Party->IsMaster || thisclient->CharInfo->charid==charid) return true; CParty* party = thisclient->Party->party; CPlayer* thismember = party->GetMemberByCharID( charid ); if(thismember==NULL) return true; BEGINPACKET( pak, 0x7d1 ); // Kicked from party message ADDBYTE ( pak, 0x80 ); ADDDWORD ( pak, thismember->CharInfo->charid ); thismember->client->SendPacket( &pak ); RESETPACKET( pak, 0x7d2 ); ADDWORD ( pak, 0xff00 ); ADDDWORD ( pak, thismember->CharInfo->charid ); bool pflag = false; if(!party->RemovePlayer( thismember )) //if this player is not in this party return true; if(party->Members.size()>1) { for(UINT i=0;i<party->Members.size();i++) { CPlayer* othermember = party->Members.at(i); if(!pflag) { ADDDWORD( pak, othermember->CharInfo->charid ); if(thismember->Party->IsMaster) othermember->Party->IsMaster = true; pflag = true; } othermember->client->SendPacket( &pak ); } } else { for(UINT i=0;i<party->Members.size();i++) { CPlayer* othermember = party->Members.at(i); BEGINPACKET( pak, 0x7d1 ); ADDBYTE ( pak, 0x05 ); ADDWORD ( pak, 0x0000 ); ADDWORD ( pak, 0x0000 ); othermember->client->SendPacket( &pak ); othermember->Party->party = NULL; othermember->Party->IsMaster = true; } RemoveParty( party ); delete party; } } break; default: Log(MSG_WARNING,"Party unknown action: %i", action); } return true; }
// Party Manager bool CWorldServer::pakPartyManager( CPlayer* thisclient, CPacket* P ) { unsigned int action = GETBYTE((*P),0); switch(action) { case 0x02://Acepto { if(thisclient->Party->party!=NULL)// have party return true; unsigned int clientid = GETWORD((*P),1); if (clientid == thisclient->clientid) { Log(MSG_WARNING, "User %s tried to party with himself\n", thisclient->CharInfo->charname); return false; //kick the cheater } CPlayer* otherclient = GetClientByID( clientid, thisclient->Position->Map ); if(otherclient==NULL) { BEGINPACKET( pak, 0x7d1 ); ADDBYTE ( pak, 0x00 );//No encontro el ID ADDWORD ( pak, clientid ); ADDBYTE ( pak, 0x00 ); thisclient->client->SendPacket( &pak ); return true; } CParty* party = otherclient->Party->party; if(party!=NULL) { //LMA: Refreshing Capacity if needed party->RefreshMax(); if(party->Members.size()>=party->Capacity) { SendSysMsg( thisclient, "Party is Full" ); return true; } } if(abs(otherclient->Stats->Level-thisclient->Stats->Level)>(Config.Partygap+1)) { BEGINPACKET( pak, 0x7d1 ); ADDBYTE ( pak, 0x07 );//Level inapropiado ADDWORD ( pak, clientid ); ADDBYTE ( pak, 0x00 ); thisclient->client->SendPacket( &pak ); return true; } BEGINPACKET( pak, 0x7d1 ); ADDBYTE ( pak, 0x02 );//Acepto Party ADDWORD ( pak, otherclient->clientid ); ADDBYTE ( pak, 0x00 ); otherclient->client->SendPacket( &pak ); if( party==NULL ) { // new party CParty* thisparty = new CParty; thisparty->AddPlayer( otherclient ); AddParty( thisparty ); otherclient->Party->IsMaster = true; party = thisparty; } //Send Party Level and Party Exp RESETPACKET( pak, 0x7d4 ); // ADDBYTE ( pak, party->PartyLevel ); ADDDWORD ( pak, party->Exp ); thisclient->client->SendPacket( &pak ); thisclient->Party->IsMaster = false; // Send New Party Member info to other players RESETPACKET( pak, 0x7d2 ); ADDBYTE ( pak, party->Option ); ADDBYTE ( pak, 0x01 ); ADDDWORD ( pak, thisclient->CharInfo->charid ); ADDWORD ( pak, thisclient->clientid ); ADDWORD ( pak, thisclient->Stats->MaxHP ); ADDWORD ( pak, thisclient->Stats->HP ); //ADDDWORD ( pak, 0x00000000 );//Tomiz: Was not commented before ADDDWORD ( pak, BuildBuffs( thisclient ));//Tomiz: Buff Data //ADDDWORD ( pak, 0x0000000f );//Tomiz: Was not commented before ADDDWORD ( pak, 0x1f40008c );//Tomiz ADDWORD ( pak, 0x1388 ); ADDSTRING ( pak, thisclient->CharInfo->charname ); ADDBYTE ( pak, 0x00 ); party->SendToMembers( &pak ); // Send To New Party Member the members List RESETPACKET( pak, 0x7d2 ); ADDBYTE ( pak, party->Option ); ADDBYTE ( pak, party->Members.size() ); for(int i=0;i<party->Members.size();i++) { CPlayer* member= party->Members.at(i); ADDDWORD ( pak, member->CharInfo->charid ); ADDWORD ( pak, member->clientid ); ADDWORD ( pak, member->Stats->MaxHP ); ADDWORD ( pak, member->Stats->HP ); //ADDDWORD ( pak, 0x00000000 );//Tomiz: Was not commented before ADDDWORD ( pak, BuildBuffs( member ));//Tomiz: Buff Data //ADDDWORD ( pak, 0x0000000f );//Tomiz: Was not commented before ADDDWORD ( pak, 0x7200005b );//Tomiz ADDWORD ( pak, 0x1388 ); ADDSTRING ( pak, member->CharInfo->charname ); ADDBYTE ( pak, 0x00 ); } thisclient->client->SendPacket( &pak ); party->AddPlayer( thisclient ); } break; case 0x04://No acepto { unsigned int clientid = GETWORD((*P),1); CPlayer* otherclient = GetClientByID( clientid, thisclient->Position->Map ); if(otherclient==NULL) { BEGINPACKET( pak, 0x7d1 ); ADDBYTE ( pak, 0x00 );//No encontro el ID ADDWORD ( pak, clientid ); ADDBYTE ( pak, 0x00 ); thisclient->client->SendPacket( &pak ); return true; } BEGINPACKET( pak, 0x7d1 ); ADDBYTE ( pak, 0x04 );//No acepto ADDWORD ( pak, thisclient->clientid ); ADDBYTE ( pak, 0x00 ); otherclient->client->SendPacket( &pak ); } break; default: Log(MSG_WARNING,"Party Manager unknown action: %i", action); } return true; }
void CPartyQuestProcessor::Process() { DWORD dwTickCount = GetTickCount(); int i; for( i = 0; i < MAX_GUILD_QUEST; i++ ) { PPARTYQUESTELEM pElem = &m_pElem[i]; if( pElem->nId == i ) { CParty* pParty = g_PartyMng.GetParty( pElem->idParty ); // if( !pGuild ) // continue; PARTYQUESTPROP* pProp = prj.GetPartyQuestProp( pElem->nId ); if( !pProp ) continue; // 제한 시간 지났다... if( pElem->dwEndTime < dwTickCount ) { switch( pElem->nProcess ) { case PQP_WORMON: { TRACE( "PQP_WORMON - r\n" ); CRect rect; rect.SetRect( pProp->x1, pProp->y2, pProp->x2, pProp->y1 ); // if( pParty ) // { // pParty->ReplaceLodestar( rect ); // } /* CMover* pWormon = prj.GetMover( pElem->objidWormon ); if( pWormon ) pWormon->Delete(); */ CPoint point; D3DXVECTOR3 vPos; point = rect.CenterPoint(); vPos.x = (float)( point.x ); vPos.z = (float)( point.y ); vPos.y = 100.0f; RemoveAllDynamicObj( pProp->dwWorldId, vPos, 500 ); RemovePartyQuest( pElem->nId ); } break; case PQP_GETITEM: { TRACE( "PQP_GETITEM - r\n" ); CRect rect; rect.SetRect( pProp->x1, pProp->y2, pProp->x2, pProp->y1 ); // if( pParty ) // { // pParty->ReplaceLodestar( rect ); // } CPoint point; D3DXVECTOR3 vPos; point = rect.CenterPoint(); vPos.x = (float)( point.x ); vPos.z = (float)( point.y ); vPos.y = 100.0f; RemoveAllDynamicObj( pProp->dwWorldId, vPos, 500 ); RemovePartyQuest( pElem->nId ); } break; default: break; } } else // 아직 열시미 잡고있는중이다~ { switch( pElem->nProcess ) { case PQP_WORMON: { TRACE( "PQP_WORMON - p\n" ); if( ++pElem->nCount < 10 ) continue; CRect rect; rect.SetRect( pProp->x1, pProp->y2, pProp->x2, pProp->y1 ); BOOL bsurvivor = FALSE; // is survivor exists? if( pParty ) { CUser* pUser; for( int k = 0 ; k < pParty->GetSizeofMember() ; k++ ) { u_long idPlayer = pParty->GetPlayerId( k ); pUser = (CUser*)prj.GetUserByID( idPlayer ); if( IsValidObj( pUser ) ) { POINT point = { (int)pUser->GetPos().x, (int)pUser->GetPos().z }; if( rect.PtInRect( point ) && pUser->IsLive() ) { bsurvivor = TRUE; break; } else { pUser->AddQuestTextTime( 0, 0, 0xffffffff ); } } } for( int k = 0 ; k < pParty->GetSizeofMember() ; k++ ) { u_long idPlayer = pParty->GetPlayerId( k ); pUser = (CUser*)prj.GetUserByID( idPlayer ); if( IsValidObj( pUser ) ) { POINT point = { (int)pUser->GetPos().x, (int)pUser->GetPos().z }; if( !rect.PtInRect( point ) ) { pUser->AddQuestTextTime( 0, 0, 0xffffffff ); } } } } if( !bsurvivor ) { // if( pParty ) // { // pParty->ReplaceLodestar( rect ); // } /* CMover* pWormon = prj.GetMover( pElem->objidWormon ); if( pWormon ) pWormon->Delete(); */ CPoint point; D3DXVECTOR3 vPos; point = rect.CenterPoint(); vPos.x = (float)( point.x ); vPos.z = (float)( point.y ); vPos.y = 100.0f; RemoveAllDynamicObj( pProp->dwWorldId, vPos, 500 ); RemovePartyQuest( pElem->nId ); } } break; case PQP_GETITEM: { TRACE( "PQP_GETITEM - p\n" ); CRect rect; rect.SetRect( pProp->x1, pProp->y2, pProp->x2, pProp->y1 ); BOOL bexist = FALSE; // is member here? if( pParty ) { CUser* pUser; for( int k = 0 ; k < pParty->GetSizeofMember() ; k++ ) { u_long idPlayer = pParty->GetPlayerId( k ); pUser = (CUser*)prj.GetUserByID( idPlayer ); if( IsValidObj( pUser ) ) { POINT point = { (int)pUser->GetPos().x, (int)pUser->GetPos().z }; if( rect.PtInRect( point ) ) { bexist = TRUE; break; } } } for( int k = 0 ; k < pParty->GetSizeofMember() ; k++ ) { u_long idPlayer = pParty->GetPlayerId( k ); pUser = (CUser*)prj.GetUserByID( idPlayer ); if( IsValidObj( pUser ) ) { POINT point = { (int)pUser->GetPos().x, (int)pUser->GetPos().z }; if( !rect.PtInRect( point ) ) { pUser->AddQuestTextTime( 0, 0, 0xffffffff ); } } } } if( !bexist ) { // if( pParty ) // { // pParty->ReplaceLodestar( rect ); // } CPoint point; D3DXVECTOR3 vPos; point = rect.CenterPoint(); vPos.x = (float)( point.x ); vPos.z = (float)( point.y ); vPos.y = 100.0f; RemoveAllDynamicObj( pProp->dwWorldId, vPos, 500 ); RemovePartyQuest( pElem->nId ); } } break; default: break; } } } } }
void CPartyMng::RemoveConnection( CPlayer* pPlayer ) { if( pPlayer->m_uPartyId == 0 ) return; CParty* pParty; CMclAutoLock Lock( m_AddRemoveLock ); pParty = GetParty( pPlayer->m_uPartyId ); if( pParty ) { int i = pParty->FindMember( pPlayer->uKey ); if( i < 0 ) return; pParty->m_aMember[i].m_tTime = CTime::GetCurrentTime(); pParty->m_aMember[i].m_bRemove = TRUE; pParty->m_nReferens++; BEFORESENDDUAL( ar, PACKETTYPE_REMOVEPLAYERPARTY, DPID_UNKNOWN, DPID_UNKNOWN ); ar << pPlayer->m_uPartyId << pPlayer->uKey; SEND( ar, &g_dpCoreSrvr, DPID_ALLPLAYERS ); #if __VER >= 12 // __PARSKILL1001 090917 mirchang - 파스킬 아이템 수정 if( pParty->m_nModeTime[PARTY_PARSKILL_MODE] ) g_dpCoreSrvr.SendSetPartyMode( pParty->m_uPartyId, PARTY_PARSKILL_MODE, FALSE ); #endif // __PARSKILL1001 090917 mirchang - 파스킬 아이템 수정 if( i == 0 ) { bool fRemoveParty = true; for( int j = 1; j < pParty->m_nSizeofMember; j++ ) { if( pParty->m_aMember[j].m_bRemove == FALSE ) { fRemoveParty = false; pParty->SwapPartyMember( 0, j ); break; } } #if __VER >= 12 // __PARSKILL1001 //12차 파스킬 아이템 수정 world,core,neuz for( int k = 0 ; k < MAX_PARTYMODE ; k++ ) { if( pParty->m_nModeTime[k] ) { if( k == PARTY_PARSKILL_MODE) continue; pParty->m_nModeTime[k] = 0; } } #endif //__PARSKILL1001 //12차 파스킬 아이템 수정 world,core,neuz if( fRemoveParty ) { CPlayer* pPlayer; for( j = 0; j < pParty->m_nSizeofMember; j++ ) { pPlayer = g_PlayerMng.GetPlayer( pParty->GetPlayerId( j ) ); if( pPlayer ) pPlayer->m_uPartyId = 0; } DeleteParty( pParty->m_uPartyId ); } } } }
void cSkillManager::NetworkMsgParse( BYTE Protocol, void* pMsg ) { switch(Protocol) { case MP_SKILL_START_SYN: { MSG_SKILL_START_SYN* pmsg = ( MSG_SKILL_START_SYN* )pMsg; CObject* object = g_pUserTable->FindUser( pmsg->Operator ); if( ! object ) { break; } // 080904 LYW --- SkillManager : 공성전 중 사용할 수 없는 스킬 체크. if( SIEGEWARFAREMGR->Is_CastleMap() == FALSE && SIEGEWARFAREMGR->IsSiegeWarfareZone() && SIEGEWARFAREMGR->GetState() > eSiegeWarfare_State_Before ) { if( SIEGEWARFAREMGR->IsFobiddenSkill(pmsg->SkillIdx) ) return ; } SKILL_RESULT result = SKILL_FAIL_ETC; if( object->GetObjectKind() == eObjectKind_Player ) result = OnSkillStartSyn( pmsg ); else if( object->GetObjectKind() == eObjectKind_Pet ) result = OnPetSkillStartSyn( pmsg ); // 080610 LUJ, 스킬 실패 시 메시지를 반환하도록 함 if( result != SKILL_SUCCESS ) { CObject* object = g_pUserTable->FindUser( pmsg->Operator ); if( ! object ) { break; } MSG_DWORD2 message; ZeroMemory( &message, sizeof( message ) ); message.Category = MP_SKILL; message.Protocol = MP_SKILL_START_NACK; message.dwData1 = pmsg->SkillIdx; message.dwData2 = result; object->SendMsg( &message, sizeof( message ) ); } } break; // 080602 LUJ, 전서버 대상 스킬이 전파됨 case MP_SKILL_START_TO_MAP: { const MSG_ITEM_SKILL_START_TO_MAP* const receivedMessage = (MSG_ITEM_SKILL_START_TO_MAP*)pMsg; const cActiveSkillInfo* const skillInfo = GetActiveInfo( receivedMessage->mSkill.wSkillIdx ); if(0 == skillInfo || TARGET_KIND_WORLD != skillInfo->GetInfo().Area) { break; } typedef std::set< DWORD > ObjectIndexSet; ObjectIndexSet objectIndexSet; switch(skillInfo->GetInfo().AreaTarget) { case eSkillAreaTargetGuild: { GUILDMEMBERINFO memberInfo[ MAX_GUILD_MEMBER ] = { 0 }; CGuild* guild = GUILDMGR->GetGuild( receivedMessage->dwObjectID ); if( ! guild ) { break; } guild->GetTotalMember( memberInfo ); for( DWORD size = sizeof( memberInfo ) / sizeof( *memberInfo ); size--; ) { objectIndexSet.insert( memberInfo[ size ].MemberIdx ); } break; } case eSkillAreaTargetFamily: { const DWORD familyIndex = receivedMessage->dwObjectID; // 080602 LUJ, 패밀리는 맵 서버에 데이타가 없고, 에이전트에 있다. 번거롭지만 // DB에 회원 목록을 쿼리해서 버프를 적용하도록 하자. // 081012 LUJ, 일부 로컬은 프로시저 호출 시 대소문자까지 일치해야 한다. 단, dbo는 소문자로 해야함. 이에 모든 프로시저 이름을 수정함 g_DB.FreeMiddleQuery( RSkillAddToFamily, skillInfo->GetIndex(), "EXEC dbo.MP_FAMILY_MEMBER_LOADINFO %d", familyIndex ); break; } case eSkillAreaTargetParty: { const DWORD partyIndex = receivedMessage->dwObjectID; CParty* party = PARTYMGR->GetParty( partyIndex ); if( ! party ) { break; } for( DWORD i = 0; i < MAX_PARTY_LISTNUM; ++i ) { objectIndexSet.insert(party->GetMemberID(i)); } break; } } // 080602 LUJ, 선택된 집단을 대상으로 버프 스킬을 적용한다 for( ObjectIndexSet::const_iterator it = objectIndexSet.begin(); objectIndexSet.end() != it; ++it ) { CPlayer* player = ( CPlayer* )g_pUserTable->FindUser( *it ); if( ! player || player->GetObjectKind() != eObjectKind_Player ) { continue; } AddBuffSkill( *player, skillInfo->GetInfo()); } break; } case MP_SKILL_UPDATE_TARGET_SYN: { MSG_SKILL_UPDATE_TARGET* pmsg = ( MSG_SKILL_UPDATE_TARGET* )pMsg; OnSkillTargetUpdate( pmsg ); } break; case MP_SKILL_CANCEL_SYN: { MSG_DWORD* pmsg = ( MSG_DWORD* )pMsg; OnSkillCancel( pmsg ); } break; // 091127 LUJ, 플레이어를 소환한다 case MP_SKILL_RECALL_SYN: { const MSG_NAME_DWORD3* const receivedMessage = (MSG_NAME_DWORD3*)pMsg; const DWORD recallPlayerIndex = receivedMessage->dwObjectID; const DWORD targetPlayerinex = receivedMessage->dwData1; const DWORD skillIndex = receivedMessage->dwData2; const MAPTYPE targetMap = MAPTYPE(receivedMessage->dwData3); LPCTSTR targetPlayerName = receivedMessage->Name; Recall( recallPlayerIndex, targetPlayerinex, targetPlayerName, targetMap, skillIndex); } break; // 100211 ONS 부활계열 스킬 사용시 대상자에게 부활의사를 묻는 처리 추가 case MP_SKILL_RESURRECT_ACK: { MSGBASE* pmsg = ( MSGBASE* )pMsg; CPlayer* pPlayer = (CPlayer*)g_pUserTable->FindUser( pmsg->dwObjectID ); if( ! pPlayer || eObjectKind_Player != pPlayer->GetObjectKind() ) { break; } const cActiveSkillInfo* const pSkillInfo = GetActiveInfo( pPlayer->GetCurResurrectIndex()); if(0 == pSkillInfo) { break; } // 부활대상이 수락했을 경우, 부활 처리를 실행한다. EXPTYPE exp = pPlayer->OnResurrect(); exp = (EXPTYPE)(exp * ( pSkillInfo->GetInfo().UnitData / 100.f )) ; if( exp ) { pPlayer->AddPlayerExpPoint( exp ); } pPlayer->SetCurResurrectIndex( 0 ); } break; // 부활 스킬에 의한 부활을 거부했을 경우 case MP_SKILL_RESURRECT_NACK: { MSGBASE* pmsg = ( MSGBASE* )pMsg; CObject* object = g_pUserTable->FindUser( pmsg->dwObjectID ); if( ! object || eObjectKind_Player != object->GetObjectKind() ) { break; } CPlayer* pPlayer = (CPlayer*)object; pPlayer->SetCurResurrectIndex( 0 ); } break; } }
void CPartyMng::Worker( void ) { CPlayer* pMember; HANDLE hHandle = m_hCloseWorker; while( WaitForSingleObject( hHandle, 1000 ) == WAIT_TIMEOUT ) { CTime timeCurr = CTime::GetCurrentTime(); CMclAutoLock Lock( g_PlayerMng.m_AddRemoveLock ); CMclAutoLock Lock2( m_AddRemoveLock ); for( C2PartyPtr::iterator i = m_2PartyPtr.begin(); i != m_2PartyPtr.end(); ) { CParty* pParty = (CParty*)i->second; ++i; if( pParty->m_nReferens > 0 ) { for( int j = 1; j < pParty->m_nSizeofMember; j++ ) { if( pParty->m_aMember[j].m_uPlayerId != 0 && pParty->m_aMember[j].m_bRemove ) { if( timeCurr.GetTime() - pParty->m_aMember[j].m_tTime.GetTime() > 60 * 10 ) // 10분 : 60 * 10 // 지금은 1분 { u_long idMember = pParty->GetPlayerId( j ); if( pParty->DeleteMember( idMember ) ) { pParty->m_nReferens--; g_dpCoreSrvr.SendRemoveParty( pParty->m_uPartyId, pParty->m_aMember[0].m_uPlayerId, idMember ); if( pParty->GetSizeofMember() < 2 ) { pMember = g_PlayerMng.GetPlayer( pParty->GetPlayerId( 0 ) ); if( pMember ) pMember->m_uPartyId = 0; DeleteParty( pParty->m_uPartyId ); break; } if( pParty->m_nReferens == 0 ) break; } } } } // for } // if // 파티모드를 체크 for( int j = 0 ; j < MAX_PARTYMODE ; j++ ) { if( pParty->m_nModeTime[j] ) { #if __VER >= 12 // __PARSKILL1001 //12차 파스킬 아이템 수정 world,core,neuz if( j == PARTY_PARSKILL_MODE) continue; #endif //__PARSKILL1001 //12차 파스킬 아이템 수정 world,core,neuz pParty->m_nModeTime[j] -= 1000; if( pParty->m_nModeTime[j] <= 0 ) { pParty->m_nModeTime[j] = 0; g_dpCoreSrvr.SendSetPartyMode( pParty->m_uPartyId, j, FALSE ); } } } } // for // TRACE( "Worker Party\n" ); } }
// Give Exp bool CWorldServer::GiveExp( CMonster* thismon ) { Log(MSG_DEBUG,"Awarding EXP"); int tmpMult = 1; if( thismon->owner != 0) // Summon { MapList.Index[thismon->Position->Map]->DeleteMonster( thismon ); return true; } // Give Experience Drops and Quest Items vector<CPartyExp*> PartyExp; vector<CParty*> PartyList; CMap* map = GServer->MapList.Index[thismon->Position->Map]; for(UINT i=0;i<thismon->PlayersDamage.size();i++) { MonsterDamage* thisplayer = thismon->PlayersDamage.at(i); CPlayer* thisclient = GetClientByCID( thisplayer->charid, thismon->Position->Map ); if( thisplayer->damage > 0 && thisclient != NULL ) //player did some damage { Log(MSG_DEBUG,"Player did %i damage. max = %i",thisplayer->damage,thismon->Stats->MaxHP); float MyPercent = (float)thisplayer->damage / thismon->Stats->MaxHP; if(MyPercent > thisclient->CharInfo->HighestOverkill) { thisclient->CharInfo->HighestOverkill = MyPercent; SendPM(thisclient, "Congratulations!! You have exceeded your highest ever Overkill rate. New Best: %f",thisclient->CharInfo->HighestOverkill); } if(MyPercent > GServer->Config.MaxOverkill)MyPercent = GServer->Config.MaxOverkill; //set overkill ceiling Log(MSG_DEBUG,"Percentage multiplier %f",MyPercent); if( thisclient->Battle->target == thismon->clientid ) { ClearBattle( thisclient->Battle ) thisclient->Position->destiny = thisclient->Position->current; //Log(MSG_DEBUG,"(GiveExp) Destiny set to current position X: %f Y: %f.",thisclient->Position->current.x,thisclient->Position->current.y); } if( thismon->MonsterDrop->firsthit == thisclient->CharInfo->charid ) { for( int q=0;q<10;q++) { // Give Quest Item if( thisclient->quest.quests[q].QuestID != 0 ) { Log(MSG_DEBUG,"Giving quest reward item for quest %i Killed monster type %i",thisclient->quest.quests[q].QuestID,thismon->montype); //P: Suppressing this completely for a test of the drop code added below //BEGINPACKET( pak, 0x731 ) //ADDWORD ( pak, thismon->montype ); //thisclient->client->SendPacket( &pak ); //PY: thismon->thisnpc->die_quest contains the hash needed to complete the trigger so we can just bypass the initial part of this process int success = thisclient->ExecuteQuestTrigger(thismon->thisnpc->die_quest); if(success == 5) // quest success { Log(MSG_DEBUG,"Death QSD Trigger %i successful. Sending success: ",thismon->thisnpc->die_quest); BEGINPACKET ( pak, 0x730); ADDBYTE ( pak, success); ADDBYTE ( pak, 0); ADDDWORD( pak, thismon->thisnpc->die_quest); thisclient->client->SendPacket(&pak); } break; } } } //assign my own exp for monsters that I personally damaged unsigned int exp = (unsigned int)floor(thismon->thisnpc->exp * MyPercent); //unsigned int exp = (unsigned int)ceil((double)((thismon->thisnpc->exp * thisplayer->damage) / (thismon->thisnpc->hp*thismon->thisnpc->level))); exp = exp * Config.EXP_RATE * map->mapXPRate; //calculate base exp for this client. No medals or stuff accounted for yet Log(MSG_DEBUG,"MonXP: %i config rate: %i Map rate : %i My percent: %f Total XP: %i", thismon->thisnpc->exp, Config.EXP_RATE, map->mapXPRate, MyPercent, exp); thisclient->CharInfo->Pending_Exp += (exp * thisclient->Stats->xprate); //store exp into thisclient's pending_exp using personal xprate adjustments Log(MSG_DEBUG,"My personal XPrate: %i ", thisclient->Stats->xprate); if( thisclient->Party->party!=NULL ) { //Log(MSG_DEBUG,"Player is in a party"); //player is in a party so scan the party members CParty* party = thisclient->Party->party; //assign a party if(party == NULL) return true; //Log(MSG_DEBUG,"party found. Counted = %i", party->counted); for(UINT p=0;p<party->Members.size();p++) //loop through all the members in the party { //Log(MSG_DEBUG,"member %i being parsed", p); if(!party->counted) { //Log(MSG_DEBUG,"party added to list. level = %i", party->PartyLevel); party->counted = true; //tag the party so we don't add it to the list twice PartyList.push_back( party ); //we will need this list later to convert pending exp to real exp } CPlayer* thismember = party->Members.at(p); //find a party member if(thismember == NULL) return true; float RawTmpExp = (exp * (party->PartyLevel + 25) / 50); unsigned int tempxp =(unsigned int)(floor)(RawTmpExp); if (tempxp < 1)tempxp = 1; //Log(MSG_DEBUG,"member %i pending exp = %i tempxp: %i", p, thismember->CharInfo->Pending_Exp, tempxp); thismember->CharInfo->Pending_Exp += tempxp; // add a percentage of thisclient's non-adjusted exp to all party members including himself //Log(MSG_DEBUG,"member %i pending exp (after tempxp) = %i", p, thismember->CharInfo->Pending_Exp); } if(party->PartyLevel < 50) //only give party exp if party level is under 50 { party->Pending_Exp += exp; //add thisclient's non-adjusted xp to the pending exp of the party } } else //not in a party so deal with all the exp now { //SendPM(thisclient, "You receive %i EXP",thisclient->CharInfo->Pending_Exp); //Log(MSG_DEBUG,"Player awarded %i experience points",thisclient->CharInfo->Pending_Exp); thisclient->CharInfo->Exp += thisclient->CharInfo->Pending_Exp; thisclient->CharInfo->Pending_Exp = 0; //if(!thisclient->CheckPlayerLevelUP()) if(thisclient->CharInfo->Exp < thisclient->GetLevelEXP()) { BEGINPACKET( pak, 0x79b ); ADDDWORD ( pak, thisclient->CharInfo->Exp ); ADDWORD ( pak, thisclient->CharInfo->stamina ); ADDWORD ( pak, thismon->clientid ); thisclient->client->SendPacket( &pak ); } } } } for(int p=0;p<PartyList.size();p++) //loop through our party list to assign final exp to all party members. We already did non-party members up there^ { CParty* thisparty = PartyList.at( p ); if(thisparty == NULL) { //Log(MSG_DEBUG,"Party not valid"); continue; } //Log(MSG_DEBUG,"Party %i exp: %i pending exp: %i", p, thisparty->Exp, thisparty->Pending_Exp ); thisparty->counted = false; //reset the boolean for next time for(UINT i=0;i<thisparty->Members.size();i++) //loop through all the members in the party { CPlayer* thismember = thisparty->Members.at(i); //find a party member if(thismember == NULL) return true; thismember->CharInfo->Exp += thismember->CharInfo->Pending_Exp; //Log(MSG_DEBUG,"Added pending exp %i to regular exp %i for member %i", thismember->CharInfo->Pending_Exp, thismember->CharInfo->Exp, i); thismember->CharInfo->Pending_Exp = 0; if(!thismember->CheckPlayerLevelUP( )) { BEGINPACKET( pak, 0x79b ); ADDDWORD ( pak, thismember->CharInfo->Exp ); ADDWORD ( pak, thismember->CharInfo->stamina ); //ADDWORD ( pak, 0 ); //PY: not needed ADDWORD ( pak, thismon->clientid ); thismember->client->SendPacket( &pak ); } } thisparty->Exp += thisparty->Pending_Exp; thisparty->Pending_Exp = 0; thisparty->m_bitLevelUP = 0; if( thisparty->Exp > GetMaxPartyExp(thisparty->PartyLevel)) //level up the party { thisparty->PartyLevel++; thisparty->Exp -= GetMaxPartyExp(thisparty->PartyLevel-1); thisparty->m_iEXP = thisparty->Exp; thisparty->m_bitLevelUP = 1; //set levelup bit. See client structure below } //PY: structure of 0x7d4 /* BYTE m_btLEVEL; struct { unsigned int m_iEXP : 31; unsigned int m_bitLevelUP : 1; } ; */ BEGINPACKET ( pak, 0x7d4 ); ADDBYTE ( pak, thisparty->PartyLevel ); ADDWORD ( pak, thisparty->m_iEXP ); // defined as 31 bits ADDWORD ( pak, thisparty->m_bitLevelUP ); // defined as 1 bit thisparty->SendToMembers( &pak ); } return true; }
// This cleans up our clients mess :P void CWorldServer::OnClientDisconnect( CClientSocket* thisclient ) { if(thisclient->player==NULL) return; CPlayer* player = (CPlayer*)thisclient->player; if(!player->Session->isLoggedIn) return; if(!player->Saved) { player->savedata(); player->Session->isLoggedIn = false; //send packet to change messenger status (offline) BEGINPACKET( pak, 0x7e1 ); ADDBYTE ( pak, 0xfa ); ADDWORD ( pak, player->CharInfo->charid ); ADDBYTE ( pak, 0x00 ); cryptPacket( (char*)&pak, NULL ); send( csock, (char*)&pak, pak.Size, 0 ); } if ( player->Fairy ) { FairyList.at(player->FairyListIndex)->assigned = false; FairyList.at(player->FairyListIndex)->LastTime = clock(); FairyList.at(player->FairyListIndex)->ListIndex = 0; FairyList.at(player->FairyListIndex)->WaitTime = Config.FairyWait * (rand()% GetFairyRange(1)+ GetFairyRange(0)); player->Fairy = false; player->FairyListIndex = 0; DoFairyStuff(player, 0); // recalculate FairyMax Config.FairyMax = (int)ceil((float)ClientList.size() / 50.0); //(1 fairy more every 50 player) } if(player->Party->party!=NULL) { CParty* party = player->Party->party; BEGINPACKET( pak, 0x7d2 ); ADDWORD ( pak, 0xff00 ); ADDDWORD ( pak, player->CharInfo->charid ); bool pflag = false; party->RemovePlayer( player ); if(party->Members.size()>1) { for(UINT i=0;i<party->Members.size();i++) { CPlayer* othermember = party->Members.at(i); if(!pflag) { ADDDWORD( pak, othermember->CharInfo->charid ); if(player->Party->IsMaster) othermember->Party->IsMaster = true; pflag = true; } othermember->client->SendPacket( &pak ); } } else { for(UINT i=0;i<party->Members.size();i++) { CPlayer* othermember = party->Members.at(i); BEGINPACKET( pak, 0x7d1 ); ADDBYTE ( pak, 0x05 ); ADDWORD ( pak, 0x0000 ); ADDWORD ( pak, 0x0000 ); othermember->client->SendPacket( &pak ); othermember->Party->party = NULL; othermember->Party->IsMaster = true; } RemoveParty( party ); delete party; party = NULL; } } DB->QExecute("UPDATE accounts SET online=false where id=%u", player->Session->userid ); }
void CWndFriendCtrl::OnRButtonUp( UINT nFlags, CPoint point ) { u_long idPlayer; #ifdef __RT_1025 Friend* pFriend; int nSelect = GetSelect( point, idPlayer, &pFriend ); #else // __RT_1025 LPFRIEND lpFriend = NULL; int nSelect = GetSelect( point, &lpFriend ); #endif // __RT_1025 if( nSelect != -1 ) { #ifdef __RT_1025 idPlayer = idPlayer; DWORD dwState = pFriend->dwState; #else // __RT_1025 idPlayer = lpFriend->dwUserId; DWORD dwState = lpFriend->dwState; #endif // __RT_1025 m_nCurSelect = nSelect; ClientToScreen( &point ); m_menu.DeleteAllMenu(); #ifdef __RT_1025 if( dwState != FRS_OFFLINE && !pFriend->bBlock ) #else // __RT_1025 if( dwState != FRS_OFFLINE && dwState != FRS_BLOCK && dwState != FRS_OFFLINEBLOCK ) #endif // __RT_1025 m_menu.AppendMenu( 0, 0 ,_T( prj.GetText( TID_APP_MESSAGE ) ) ); #ifdef __RT_1025 if( pFriend->bBlock ) #else // __RT_1025 if( dwState == FRS_BLOCK || dwState == FRS_OFFLINEBLOCK ) #endif // __RT_1025 m_menu.AppendMenu( 0, 1 ,_T( prj.GetText( TID_FRS_BLOCKRESTORE ) ) ); else m_menu.AppendMenu( 0, 1 ,_T( prj.GetText( TID_FRS_BLOCK ) ) ); m_menu.AppendMenu( 0, 2 ,_T( prj.GetText( TID_FRS_DELETE ) ) ); #ifdef __RT_1025 if( !pFriend->bBlock ) #else // __RT_1025 if( dwState != FRS_OFFLINE && dwState != FRS_OFFLINEBLOCK ) #endif // __RT_1025 { if( g_pPlayer->IsAuthHigher( AUTH_GAMEMASTER ) ) m_menu.AppendMenu( 0, 3 ,_T( prj.GetText( TID_FRS_MOVE2 ) ) ); #ifndef __RT_1025 if( dwState != FRS_BLOCK ) #endif // __RT_1025 { if( g_Party.IsMember( idPlayer ) == FALSE ) m_menu.AppendMenu( 0, 4 ,_T( prj.GetText( TID_MMI_INVITE_PARTY ) ) ); } } #ifdef __RT_1025 if( dwState == FRS_OFFLINE || pFriend->bBlock ) #else // __RT_1025 if( dwState == FRS_OFFLINE || dwState == FRS_BLOCK || dwState == FRS_OFFLINEBLOCK ) #endif // __RT_1025 m_menu.AppendMenu( 0, 6 , _T( prj.GetText( TID_GAME_TAGSEND ) ) ); m_menu.Move( point ); m_menu.SetVisible( TRUE ); m_menu.SetFocus(); } }