bool LfgGroup::RemoveOfflinePlayers() // Return true if group is empty after check { sLfgMgr.LfgLog("Remove Offline %u, premade %u", GetId(), premadePlayers.empty() ? 0 : 1); if (m_memberSlots.empty()) { sLfgMgr.LfgLog("Group %u add to delete", GetId()); sLfgMgr.AddGroupToDelete(this); return true; } PlayerList toRemove; for(member_citerator citr = m_memberSlots.begin(); citr != m_memberSlots.end(); ++citr) { sLfgMgr.LfgLog("guid %u", citr->guid); Player *plr = sObjectMgr.GetPlayer(citr->guid); if (!plr || (!plr->GetSession() && !plr->IsBeingTeleported()) || (plr->GetGroup() && plr->GetGroup() != this && plr->GetGroup()->isLfgGroup() && ((LfgGroup*)plr->GetGroup())->IsInDungeon())) { sLfgMgr.LfgLog("Add to remove"); toRemove.insert(citr->guid); } } for(PlayerList::iterator itr = toRemove.begin(); itr != toRemove.end(); ++itr) { sLfgMgr.LfgLog("Check for premade %u", *itr); PlayerList::iterator premade = premadePlayers.find(*itr); if(premade != premadePlayers.end()) { sLfgMgr.LfgLog("premade yes"); for(PlayerList::iterator prm = premadePlayers.begin(); prm != premadePlayers.end(); ++prm) { Player *plr = sObjectMgr.GetPlayer(*prm); if(!plr || !plr->GetSession()) continue; Group* group = plr->GetGroup(); if(group) { sLfgMgr.RemoveFromQueue(plr, false); return true; } } for(PlayerList::iterator prm = premadePlayers.begin(); prm != premadePlayers.end(); ++prm) RemoveMember(*prm, 0); } } for(PlayerList::iterator itr = toRemove.begin(); itr != toRemove.end(); ++itr) { sLfgMgr.LfgLog("Remove %u", *itr); RemoveMember(*itr, 0); } toRemove.clear(); //flush empty group if (GetMembersCount() == 0) { sLfgMgr.LfgLog("Group %u add to delete 2", GetId()); sLfgMgr.AddGroupToDelete(this); return true; } return false; }
void OnReceive(packet p, event e, int *members, int *pmembers, int *senders, double *avg_rtcp_size, double *tp, double tc, double tn) { /* What we do depends on whether we have left the group, and * are waiting to send a BYE (TypeOfEvent(e) == EVENT_BYE) or * an RTCP report. p represents the packet that was just received. */ if (PacketType(p) == PACKET_RTCP_REPORT) { if (NewMember(p) && (TypeOfEvent(e) == EVENT_REPORT)) { AddMember(p); *members += 1; } *avg_rtcp_size = (1./16.)*ReceivedPacketSize(p) + (15./16.)*(*avg_rtcp_size); } else if (PacketType(p) == PACKET_RTP) { if (NewMember(p) && (TypeOfEvent(e) == EVENT_REPORT)) { AddMember(p); *members += 1; } if (NewSender(p) && (TypeOfEvent(e) == EVENT_REPORT)) { AddSender(p); *senders += 1; } } else if (PacketType(p) == PACKET_BYE) { *avg_rtcp_size = (1./16.)*ReceivedPacketSize(p) + (15./16.)*(*avg_rtcp_size); if (TypeOfEvent(e) == EVENT_REPORT) { if (NewSender(p) == FALSE) { RemoveSender(p); *senders -= 1; } if (NewMember(p) == FALSE) { RemoveMember(p); *members -= 1; } if(*members < *pmembers) { tn = tc + (((double) *members)/(*pmembers))*(tn - tc); *tp = tc - (((double) *members)/(*pmembers))*(tc - *tp); /* Reschedule the next report for time tn */ Reschedule(tn, e); *pmembers = *members; } } else if (TypeOfEvent(e) == EVENT_BYE) { *members += 1; } } }
void CChatChannel::KickMember(CChatMember *pByMember, CChatMember *pMember) { ADDTOCALLSTACK("CChatChannel::KickMember"); ASSERT(pMember); LPCTSTR pszByName = "SYSTEM"; if ( pByMember ) { pszByName = pByMember->GetChatName(); if ( !IsModerator(pszByName) ) { pByMember->SendChatMsg(CHATMSG_MustHaveOps); return; } } // Remove from moderators list LPCTSTR pszName = pMember->GetChatName(); if ( IsModerator(pszName) ) { SetModerator(pszName, true); SendMember(pMember); Broadcast(CHATMSG_PlayerNoLongerModerator, pszName); pMember->SendChatMsg(CHATMSG_RemovedListModerators, pszByName); } pMember->SendChatMsg(CHATMSG_ModeratorHasKicked, pszByName); pMember->SendChatMsg(CHATCMD_ClearMembers); Broadcast(CHATMSG_PlayerKicked, pszName); RemoveMember(pMember); }
void ArenaTeam::Destroy() { char buffer[1024]; WorldPacket * data; vector<PlayerInfo*> tokill; uint32 i; tokill.reserve(m_memberCount); snprintf(buffer,1024, "The arena team, '%s', disbanded.", m_name.c_str()); data = sChatHandler.FillSystemMessageData(buffer); SendPacket(data); delete data; for(i = 0; i < m_memberCount; ++i) { if(m_members[i].Info) tokill.push_back(m_members[i].Info); } for(vector<PlayerInfo*>::iterator itr = tokill.begin(); itr != tokill.end(); itr++) { RemoveMember(*itr); } objmgr.RemoveArenaTeam(this); delete this; }
/*------------------------------------------------------------------------ ------------------------- Execute the photoflo --------------------------- ------------------------------------------------------------------------*/ static Bool execute(floDefPtr flo, peTexPtr importer) { bandMsk ready; peTexPtr pet; peDefPtr ped; pedLstPtr lst = ListEmpty(&flo->optDAG) ? &flo->defDAG : &flo->optDAG; CARD32 sched_count = SCHED_BAIL_OUT; CARD32 strip_count = flo->floTex->putCnt; if(importer) { /* Put the ImportClient element at the head of the ready-list */ InsertMember(importer,&flo->floTex->schedHead); importer->scheduled = importer->receptor[IMPORT].ready; } do { /* execute elements from the head of the ready-list until it's empty * (calls to schedule from the data manager may prepend * additional elements to the ready-list) */ while(!ListEmpty(&flo->floTex->schedHead)) { pet = flo->floTex->schedHead.flink; if(Activate(flo,pet->peDef,pet) && (ready = runnable(flo,pet))) { pet->scheduled = ready; /* remember which bands keep us alive */ } else { /* element is no longer runnable, remove it and check for errors */ RemoveMember(pet,pet); pet->scheduled = 0; if(ferrCode(flo)) return(flo->flags.active = FALSE); } if(strip_count != flo->floTex->putCnt) { sched_count = SCHED_BAIL_OUT; strip_count = flo->floTex->putCnt; } else if( !--sched_count) ImplementationError(flo,pet->peDef, return(FALSE)); } /* Load all the elements onto the ready-list that can keep producing * output without requiring any additional input (e.g. ImportResource * elements). */ for(ped = lst->flink; !ListEnd(ped,lst); ped = ped->flink) if(ped->peTex->emitting && !ped->peTex->admissionCnt) InsertMember(ped->peTex,&flo->floTex->schedHead); /* * keep on trucking if there's nothing expected from the client */ } while(!flo->floTex->imports && !ListEmpty(&flo->floTex->schedHead)); /* if we still have stuff to do, count another round, otherwise shut it down */ if(flo->floTex->imports || flo->floTex->exports) ++flo->floTex->exitCnt; else ddShutdown(flo); return(flo->flags.active); } /* end execute */
rtperror UpdateMemberInfoByBYE(_RTP_CONTEXT *the_context, rtcp_packet *the_packet, struct sockaddr *fromaddr, int addrlen) { member *pkt_origin_member; u_int32 cur_ssrc; unsigned int ssrc_iter; int i; rtcp_bye_block bb; /* Copy the reason code (non null terminated) from the packet into the context variable, so it can be returned to the callback */ for(i = 0; i < the_packet->variant.bye.reason_length; i++) { the_context->byereason[i] = the_packet->variant.bye.reason[i]; } the_context->byereason[i] = '\0'; /* Update info for the various members */ for (ssrc_iter=0; ssrc_iter < RTCP_RC(*the_packet->common); ssrc_iter++){ bb = RTPGetByeBlock(the_packet, ssrc_iter); cur_ssrc = bb.ssrccsrc; pkt_origin_member = UpdateTimeOrCreateMember(the_context, cur_ssrc, fromaddr, addrlen, TRUE, RTP_MEMBER_PENDING); /* The member that is about to go BYE has been placed on the membership list if it wasn't already there, and timestamped with the current time (since we just received a BYE packet for it, the current time is appropriate). We now destroy it unless the BYE was (believed to be) due to a collision and the CNAME is known. In such a case, we leave the member on the member-list. Note that the remove will fail if the member is in the CSRC list */ if (!pkt_origin_member->colliding || pkt_origin_member->sdes_info[0] == NULL){ RemoveMember(the_context, pkt_origin_member); if (the_context->UpdateMemberCallBack != NULL){ the_context->UpdateMemberCallBack(the_context->context_num, pkt_origin_member->unique_id, RTP_FLAG_MEMBER_LEAVES, the_context->byereason); } DestroyMember(the_context, pkt_origin_member); } } return(RTP_OK); }
//================================================================================ // Pensamiento //================================================================================ void CSquad::Think() { if ( IsEmpty() ) return; // Checamos a los miembros FOR_EACH_VEC( m_nMembers, it ) { CPlayer *pMember = GetMember( it ); if ( !pMember ) { RemoveMember( it ); continue; } if ( !pMember->IsAlive() ) RemoveMember( pMember ); }
void LFGProposal::RemoveDecliner(ObjectGuid guid) { if (guid.IsEmpty()) return; RemoveMember(guid); declinerGuids.insert(guid); };
void GROUPAI::DisbandGroup() { while(!m_members.empty()) { RemoveMember(m_members[0]); } m_members.clear(); m_visibleEnemies.clear(); }
void LFGProposal::RemoveDecliner(ObjectGuid guid) { if (guid.IsEmpty()) return; RemoveMember(guid); LFGMgr::WriteGuard Guard(sLFGMgr.GetLock()); declinerGuids.insert(guid); };
bool CChatChannel::RemoveMember(LPCTSTR pszName) { ADDTOCALLSTACK("CChatChannel::RemoveMember(2)"); CChatMember *pMember = FindMember(pszName); if ( !pMember ) return false; RemoveMember(pMember); return true; }
bool LfgGroup::SelectRandomDungeon() { m_originalInfo = m_dungeonInfo; m_lfgFlags |= LFG_GRP_RANDOM; LfgLocksMap *groupLocks = GetLocksList(); std::vector<LFGDungeonEntry const*> options; LFGDungeonEntry const *currentRow = NULL; //Possible dungeons LfgDungeonList* list = sLfgMgr.GetRandomOptions(m_dungeonInfo->ID); for(LfgDungeonList::iterator itr = list->begin(); itr != list->end(); ++itr) options.push_back(*itr); //And now get only without locks for(LfgLocksMap::iterator itr = groupLocks->begin(); itr != groupLocks->end(); ++itr) { for(LfgLocksList::iterator itr2 = itr->second->begin(); itr2 != itr->second->end(); ++itr2) { for(std::vector<LFGDungeonEntry const*>::iterator itrDung = options.begin(); itrDung != options.end(); ++itrDung) { if ((*itrDung)->ID != (*itr2)->dungeonInfo->ID) continue; DungeonInfo* dungeonInfo = sLfgMgr.GetDungeonInfo((*itr2)->dungeonInfo->ID); if (dungeonInfo->locked || (*itr2)->lockType != LFG_LOCKSTATUS_RAID_LOCKED) { options.erase(itrDung); break; } } } } //This should not happen if (options.empty()) { PlayerList toRemove; for(member_witerator itr = m_memberSlots.begin(); itr != m_memberSlots.end(); ++itr) { Player *plr = sObjectMgr.GetPlayer(itr->guid); if (!plr) continue; sLfgMgr.SendLfgUpdatePlayer(plr, LFG_UPDATETYPE_GROUP_DISBAND); sLog.outError("LfgMgr: Cannot find any random dungeons for player %s", plr->GetName()); plr->GetSession()->SendNotification("Cannot find any random dungeons for this group, you have to find new group. We are sorry"); toRemove.insert(plr->GetGUID()); } for(PlayerList::iterator itr = toRemove.begin(); itr != toRemove.end(); ++itr) RemoveMember(*itr, 0); toRemove.clear(); sLfgMgr.AddGroupToDelete(this); return false; } //Select dungeon, there should be also bind check uint32 tmp = time(NULL)%options.size(); m_dungeonInfo = options[tmp]; return true; }
void CParty::RemoveMemberByName(int8* MemberName) { DSP_DEBUG_BREAK_IF(m_PartyType != PARTY_PCS); for (uint32 i = 0; i < members.size(); ++i) { if (strcmp(MemberName, members.at(i)->GetName()) == 0) { RemoveMember(members.at(i)); return; } } ShowError(CL_RED"The character with name <%s> isn't found in party\n" CL_RESET, MemberName); }
void CChatChannel::KickMember(CChatChanMember *pByMember, CChatChanMember * pMember ) { ADDTOCALLSTACK("CChatChannel::KickMember"); ASSERT( pMember ); LPCTSTR pszByName; if (pByMember) // If NULL, then an ADMIN or a GM did it { pszByName = pByMember->GetChatName(); if (!IsModerator(pszByName)) { pByMember->SendChatMsg(CHATMSG_MustHaveOps); return; } } else { pszByName = "SYSTEM"; } LPCTSTR pszName = pMember->GetChatName(); // Kicking this person...remove from list of moderators first if (IsModerator(pszName)) { SetModerator(pszName, false); SendThisMember(pMember); Broadcast(CHATMSG_PlayerNoLongerModerator, pszName, ""); pMember->SendChatMsg(CHATMSG_RemovedListModerators, pszByName); } // Now kick them if (m_Members.GetCount() == 1) // If kicking yourself, send out to all clients in a chat that the channel is gone g_Serv.m_Chats.SendDeleteChannel(this); // Remove them from the channels list of members RemoveMember(pMember); // Tell the remain members about this Broadcast(CHATMSG_PlayerIsKicked, pszName, ""); // Now clear their channel member list pMember->SendChatMsg(CHATMSG_ClearMemberList); // And give them the bad news pMember->SendChatMsg(CHATMSG_ModeratorHasKicked, pszByName); }
void CParty::RemovePartyLeader(CBattleEntity* PEntity) { DSP_DEBUG_BREAK_IF(members.empty()); int ret = Sql_Query(SqlHandle, "SELECT charname FROM accounts_sessions JOIN chars ON accounts_sessions.charid = chars.charid \ JOIN accounts_parties ON accounts_parties.charid = chars.charid WHERE partyid = %u AND NOT partyflag & %d \ ORDER BY timestamp ASC LIMIT 1;", m_PartyID, PARTY_LEADER); if (ret != SQL_ERROR && Sql_NumRows(SqlHandle) != 0 && Sql_NextRow(SqlHandle) == SQL_SUCCESS) { SetLeader(Sql_GetData(SqlHandle, 0)); } if (m_PLeader == PEntity) { DisbandParty(); } else { RemoveMember(PEntity); } }
GROUPAI* GROUPAI::SplitGroup(std::vector<int> units) { if(units.empty() || m_members.empty())return NULL; GROUPAI *newGroup = new GROUPAI(m_pMaster); try { bool done = false; while(!done) { //Transfer member for(int i=0;i<(int)m_members.size();i++) if(!m_members[i]->m_isBuilding && m_members[i]->m_type == units[0]) { MAPOBJECT* unit = m_members[i]; RemoveMember(unit); newGroup->AddMember(unit); break; } units.erase(units.begin()); done = units.empty() || m_members.empty(); } if(newGroup->isDead()) { delete newGroup; newGroup = NULL; } } catch(...) { debug.Print("Error in GROUPAI::SplitGroup()"); } return newGroup; }
void CParty::RemovePartyLeader(CBattleEntity* PEntity) { DSP_DEBUG_BREAK_IF(members.empty()); DSP_DEBUG_BREAK_IF(m_PLeader != PEntity); DSP_DEBUG_BREAK_IF(PEntity->objtype != TYPE_PC); if (members.size() == 1) { DisbandParty(); } else { for (uint32 i = 0; i < members.size(); ++i) { if (PEntity != members.at(i)) { SetLeader(members.at(i)); break; } } RemoveMember(PEntity); } }
// return true = remove from update list, false = continue bool LfgGroup::UpdateVoteToKick(uint32 diff) { if (!m_voteToKick.isInProggres) return true; if (diff) { if (m_voteToKick.GetTimeLeft() <= 0) { m_voteToKick.isInProggres = false; for(member_citerator citr = m_memberSlots.begin(); citr != m_memberSlots.end(); ++citr) { Player *member = sObjectMgr.GetPlayer(citr->guid); if (!member || !member->GetSession()) continue; SendBootPlayer(member); } m_voteToKick.Reset(); return true; } return false; } //Send Update for(member_citerator citr = m_memberSlots.begin(); citr != m_memberSlots.end(); ++citr) { Player *member = sObjectMgr.GetPlayer(citr->guid); if (!member || !member->GetSession()) continue; SendBootPlayer(member); } if (m_voteToKick.GetVotesNum(false) < 3) return false; else if (m_voteToKick.GetVotesNum(true) >= 3) { Player *victim = sObjectMgr.GetPlayer(m_voteToKick.victim); sLfgMgr.LfgLog("Remove member - afk rolecheck"); RemoveMember(m_voteToKick.victim, 1); if (victim && victim->GetSession()) { victim->ScheduleDelayedOperation(DELAYED_LFG_MOUNT_RESTORE); victim->ScheduleDelayedOperation(DELAYED_LFG_TAXI_RESTORE); victim->ScheduleDelayedOperation(DELAYED_LFG_CLEAR_LOCKS); victim->RemoveAurasDueToSpell(LFG_BOOST); WorldLocation teleLoc = victim->m_lookingForGroup.joinLoc; if (!teleLoc.coords.isNULL()) victim->TeleportTo(teleLoc); else victim->TeleportToHomebind(); } else { AreaTrigger const *trigger = sObjectMgr.GetGoBackTrigger(GetDungeonInfo()->map); if(trigger) Player::SavePositionInDB(trigger->target_mapId, trigger->target_X, trigger->target_Y, trigger->target_Z, trigger->target_Orientation, sTerrainMgr.GetZoneId(trigger->target_mapId, trigger->target_X, trigger->target_Y, trigger->target_Z), m_voteToKick.victim); } //Change leader if (m_voteToKick.victim == m_leaderGuid) { for(member_citerator citr = m_memberSlots.begin(); citr != m_memberSlots.end(); ++citr) { Player *plr = sObjectMgr.GetPlayer(citr->guid); if (!plr || !plr->GetSession()) continue; if (plr->m_lookingForGroup.roles & LEADER) { ChangeLeader(plr->GetGUID()); break; } } if (m_voteToKick.victim == m_leaderGuid) ChangeLeader(GetFirstMember()->getSource()->GetGUID()); } m_voteToKick.Reset(); SendUpdate(); return true; } return false; }
void UpdateMembershipLists(_RTP_CONTEXT *the_context){ struct timeval now; struct link *cur_link, *prev_link; gettimeofday(&now, NULL); /* Lists are sorted in increasing timestamp order, so anyone that expires would be at the front of the list */ /* First we do sender list */ TimeOutPurportedSenders(the_context); TimeOutSenders(the_context); /* Next we do member list for hard timeouts. If a hard timeout occurs, regardless of the member's state, it is removed from the memberlist barring the following exceptions: If the member on the list is the local member. If the member appears in the SSRC list */ cur_link = the_context->RTP_MemberList.actual_list.last_link; while (cur_link != NULL){ prev_link = cur_link->prev_link; if (cur_link->my_member == the_context->my_memberinfo){ /* We don't ever want to take ourselves off the membership list until we send BYE */ cur_link = prev_link; continue; } if (cur_link->my_member->on_csrc_list == TRUE){ /* CSRC stay as well */ cur_link = prev_link; continue; } /* Any member that hard timeouts should be removed If the current link hasn't hard timed out, then no further members on the list will hard time out either, and we can abort the check. */ if (HardTimedOut(the_context, cur_link->my_member, now)){ member *the_member = cur_link->my_member; RemoveMember(the_context, cur_link->my_member); if (the_context->UpdateMemberCallBack != NULL){ the_context->UpdateMemberCallBack(the_context->context_num, the_member->unique_id, RTP_FLAG_DELETED_MEMBER, NULL); } DestroyMember(the_context, the_member); } else { break; } /* Move onto the next link and check for more hard timeouts */ cur_link = prev_link; } /* Now check for soft timeouts on the memberlist. We jump right to the oldest_not_yet_soft because any older links have already soft timed-out. */ cur_link = the_context->RTP_MemberList.oldest_not_yet_soft; while (cur_link != NULL){ if (SoftTimedOut(the_context, cur_link->my_member, now)){ prev_link = cur_link->prev_link; if (cur_link->my_member == the_context->my_memberinfo){ /* We don't ever want to change our own status */ cur_link = prev_link; continue; } /* Don't time out the CSRC members either */ if(cur_link->my_member->on_csrc_list == TRUE) { cur_link = prev_link; continue; } if (cur_link->my_member->status == RTP_MEMBER_CONFIRMED){ /* confirmed members become expired */ ChangeMemberStatus(the_context, cur_link->my_member, RTP_MEMBER_EXPIRED); } else if (cur_link->my_member->status == RTP_MEMBER_CONFIRMED_CONTRIBUTOR) { /* confirmed contributors become expired contributors */ ChangeMemberStatus(the_context, cur_link->my_member, RTP_MEMBER_EXPIRED_CONTRIBUTOR); } else if ((cur_link->my_member->status == RTP_MEMBER_PENDING) || (cur_link->my_member->status == RTP_MEMBER_PENDING_CONTRIBUTOR)) { member *the_member = cur_link->my_member; /* Pending members get destroyed on soft_timeouts */ RemoveMember(the_context, the_member); if (the_context->UpdateMemberCallBack != NULL){ the_context->UpdateMemberCallBack(the_context->context_num, the_member->unique_id, RTP_FLAG_DELETED_PENDING, NULL); } DestroyMember(the_context, the_member); } cur_link = prev_link; } /* Went beyond the soft timeout point */ else break; } /* When we reach here, cur_link is set to the oldest member that hasn't soft timed out yet. If no such members exist, it equals NULL */ the_context->RTP_MemberList.oldest_not_yet_soft = cur_link; return; }
void GROUPAI::GroupAI() { if(m_members.empty() || m_pMaster == NULL)return; int memberStates[] = {0, 0, 0}; m_state = GROUP_STATE_IDLE; std::vector<MAPOBJECT*>::iterator i; for(i = m_members.begin();i != m_members.end();) { if((*i) == NULL || (*i)->m_dead) { //Remove dead Group m_members RemoveMember(*i); } else { (*i)->m_pGroup = this; //determine group m_state if(!(*i)->m_isBuilding) { UNIT *unit = (UNIT*)(*i); if(unit->m_state == STATE_ATTACK) memberStates[GROUP_STATE_BATTLE]++; else if(unit->m_moving) memberStates[GROUP_STATE_MOVING]++; else memberStates[GROUP_STATE_IDLE]++; } i++; } } //Set group state if(memberStates[GROUP_STATE_BATTLE] >= m_members.size() * 0.2f) m_state = GROUP_STATE_BATTLE; else if(memberStates[GROUP_STATE_MOVING] >= m_members.size() * 0.4f) m_state = GROUP_STATE_MOVING; else m_state = GROUP_STATE_IDLE; //Group state machine switch(m_state) { case GROUP_STATE_IDLE: { if(m_task == TASK_SCOUT) { AREA *area = m_pMaster->m_pStrategyMap->GetScoutArea(GetCenter()); if(area != NULL)Goto(area->m_mapArea); } else if(m_task == TASK_ATTACK_LOCATION) { AREA *area = m_pMaster->m_pStrategyMap->GetAttackArea(GetCenter()); if(area != NULL)Goto(area->m_mapArea); } else if(m_task == TASK_NONE || m_task == TASK_DEFEND_LOCATION) { Shuffle(); } break; } case GROUP_STATE_MOVING: { Attack(m_visibleEnemies); break; } case GROUP_STATE_BATTLE: { Attack(m_visibleEnemies); if(m_task == TASK_DEFEND_LOCATION) RetreatTo(m_mapArea); break; } } //Report enemies to Master AI m_pMaster->EnemiesSpotted(m_visibleEnemies); m_visibleEnemies.clear(); }
bool CPartyDef::r_Verb( CScript &s, CTextConsole *pSrc ) { ADDTOCALLSTACK("CPartyDef::r_Verb"); EXC_TRY("Verb"); ASSERT(pSrc); LPCTSTR pszKey = s.GetKey(); CScriptObj *pRef; if ( r_GetRef(pszKey, pRef) ) { if ( pszKey[0] ) { if ( !pRef ) return true; CScript script(pszKey, s.GetArgStr()); return pRef->r_Verb(script, pSrc); } } int iIndex = FindTableSorted(pszKey, sm_szVerbKeys, COUNTOF(sm_szVerbKeys) - 1); switch ( iIndex ) { case PDV_ADDMEMBER: case PDV_ADDMEMBERFORCED: { bool bForced = (iIndex == PDV_ADDMEMBERFORCED); CGrayUID toAdd = static_cast<CGrayUID>(s.GetArgVal()); CChar *pCharAdd = toAdd.CharFind(); CChar *pCharMaster = GetMaster().CharFind(); if ( !pCharAdd || IsInParty(pCharAdd) ) return false; if ( pCharMaster && !bForced ) pCharMaster->SetKeyNum("PARTY_LASTINVITE", (long long)toAdd); return CPartyDef::AcceptEvent(pCharAdd, GetMaster(), bForced); } break; case PDV_CLEARTAGS: { LPCTSTR pszArg = s.GetArgStr(); SKIP_SEPARATORS(pszArg); m_TagDefs.ClearKeys(pszArg); } break; case PDV_CREATE: return true; case PDV_DISBAND: return Disband(GetMaster()); case PDV_MESSAGE: break; case PDV_REMOVEMEMBER: { CGrayUID toRemove; LPCTSTR pszArg = s.GetArgStr(); if ( *pszArg == '@' ) { pszArg++; size_t nMember = Exp_GetVal(pszArg); if ( !m_Chars.IsValidIndex(nMember) ) return false; toRemove = m_Chars.GetChar(nMember); } else toRemove = static_cast<CGrayUID>(s.GetArgVal()); if ( toRemove ) return RemoveMember(toRemove, GetMaster()); return false; } break; case PDV_SETMASTER: { CGrayUID newMaster; LPCTSTR pszArg = s.GetArgStr(); if ( *pszArg == '@' ) { pszArg++; size_t nMember = Exp_GetVal(pszArg); if ( nMember == 0 || !m_Chars.IsValidIndex(nMember) ) return false; newMaster = m_Chars.GetChar(nMember); } else newMaster = static_cast<CGrayUID>(s.GetArgVal()); if ( newMaster ) return SetMaster(newMaster.CharFind()); return false; } break; case PDV_SYSMESSAGE: { CGrayUID toSysmessage; LPCTSTR pszArg = s.GetArgStr(); TCHAR *pUid = Str_GetTemp(); size_t x = 0; if ( *pszArg == '@' ) { pszArg++; if ( *pszArg != '@' ) { LPCTSTR __pszArg = pszArg; while ( *pszArg != ' ' ) { pszArg++; x++; } strcpylen(pUid, __pszArg, ++x); size_t nMember = Exp_GetVal(pUid); if ( !m_Chars.IsValidIndex(nMember) ) return false; toSysmessage = m_Chars.GetChar(nMember); } } else { LPCTSTR __pszArg = pszArg; while ( *pszArg != ' ' ) { pszArg++; x++; } strcpylen(pUid, __pszArg, ++x); toSysmessage = static_cast<CGrayUID>(Exp_GetVal(pUid)); } SKIP_SEPARATORS(pszArg); if ( toSysmessage ) { CChar *pSend = toSysmessage.CharFind(); pSend->SysMessage(pszArg); } else SysMessageAll(pszArg); } break; case PDV_TAGLIST: m_TagDefs.DumpKeys(pSrc, "TAG."); break; default: return false; } return true; EXC_CATCH; EXC_DEBUG_START; EXC_ADD_SCRIPTSRC; EXC_DEBUG_END; return false; }