bool Group::Create(ObjectGuid guid, const char* name) { m_leaderGuid = guid; m_leaderName = name; m_groupType = isBGGroup() ? GROUPTYPE_BGRAID : GROUPTYPE_NORMAL; if (m_groupType & GROUPTYPE_RAID) _initRaidSubGroupsCounter(); m_lootMethod = GROUP_LOOT; m_lootThreshold = ITEM_QUALITY_UNCOMMON; m_masterLooterGuid = guid; m_currentLooterGuid = guid; // used for round robin looter m_dungeonDifficulty = DUNGEON_DIFFICULTY_NORMAL; m_raidDifficulty = RAID_DIFFICULTY_10MAN_NORMAL; if (!isBGGroup()) { m_Id = sObjectMgr.GenerateGroupLowGuid(); Player* leader = sObjectMgr.GetPlayer(guid); if (leader) { m_dungeonDifficulty = leader->GetDungeonDifficulty(); m_raidDifficulty = leader->GetRaidDifficulty(); } Player::ConvertInstancesToGroup(leader, this, guid); // store group in database CharacterDatabase.BeginTransaction(); CharacterDatabase.PExecute("DELETE FROM groups WHERE groupId ='%u'", m_Id); CharacterDatabase.PExecute("DELETE FROM group_member WHERE groupId ='%u'", m_Id); CharacterDatabase.PExecute("INSERT INTO groups (groupId,leaderGuid,mainTank,mainAssistant,lootMethod,looterGuid,lootThreshold,icon1,icon2,icon3,icon4,icon5,icon6,icon7,icon8,groupType,difficulty,raiddifficulty) " "VALUES ('%u','%u','%u','%u','%u','%u','%u','" UI64FMTD "','" UI64FMTD "','" UI64FMTD "','" UI64FMTD "','" UI64FMTD "','" UI64FMTD "','" UI64FMTD "','" UI64FMTD "','%u','%u','%u')", m_Id, m_leaderGuid.GetCounter(), m_mainTankGuid.GetCounter(), m_mainAssistantGuid.GetCounter(), uint32(m_lootMethod), m_masterLooterGuid.GetCounter(), uint32(m_lootThreshold), m_targetIcons[0].GetRawValue(), m_targetIcons[1].GetRawValue(), m_targetIcons[2].GetRawValue(), m_targetIcons[3].GetRawValue(), m_targetIcons[4].GetRawValue(), m_targetIcons[5].GetRawValue(), m_targetIcons[6].GetRawValue(), m_targetIcons[7].GetRawValue(), uint8(m_groupType), uint32(m_dungeonDifficulty), uint32(m_raidDifficulty)); } if (!AddMember(guid, name)) return false; if (!isBGGroup()) CharacterDatabase.CommitTransaction(); _updateLeaderFlag(); return true; }
void WorldSession::HandleGroupInviteOpcode(WorldPacket& recvData) { TC_LOG_DEBUG(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_GROUP_INVITE"); ObjectGuid crossRealmGuid; // unused recvData.read_skip<uint32>(); // Non-zero in cross realm invites recvData.read_skip<uint32>(); // Always 0 crossRealmGuid[2] = recvData.ReadBit(); crossRealmGuid[7] = recvData.ReadBit(); uint8 realmLen = recvData.ReadBits(9); crossRealmGuid[3] = recvData.ReadBit(); uint8 nameLen = recvData.ReadBits(10); crossRealmGuid[5] = recvData.ReadBit(); crossRealmGuid[4] = recvData.ReadBit(); crossRealmGuid[6] = recvData.ReadBit(); crossRealmGuid[0] = recvData.ReadBit(); crossRealmGuid[1] = recvData.ReadBit(); recvData.ReadByteSeq(crossRealmGuid[4]); recvData.ReadByteSeq(crossRealmGuid[7]); recvData.ReadByteSeq(crossRealmGuid[6]); std::string memberName, realmName; memberName = recvData.ReadString(nameLen); realmName = recvData.ReadString(realmLen); // unused recvData.ReadByteSeq(crossRealmGuid[1]); recvData.ReadByteSeq(crossRealmGuid[0]); recvData.ReadByteSeq(crossRealmGuid[5]); recvData.ReadByteSeq(crossRealmGuid[3]); recvData.ReadByteSeq(crossRealmGuid[2]); // attempt add selected player // cheating if (!normalizePlayerName(memberName)) { SendPartyResult(PARTY_OP_INVITE, memberName, ERR_BAD_PLAYER_NAME_S); return; } Player* player = sObjectAccessor->FindPlayerByName(memberName); // no player if (!player) { SendPartyResult(PARTY_OP_INVITE, memberName, ERR_BAD_PLAYER_NAME_S); return; } // restrict invite to GMs if (!sWorld->getBoolConfig(CONFIG_ALLOW_GM_GROUP) && !GetPlayer()->IsGameMaster() && player->IsGameMaster()) { SendPartyResult(PARTY_OP_INVITE, memberName, ERR_BAD_PLAYER_NAME_S); return; } // can't group with if (!GetPlayer()->IsGameMaster() && !sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GROUP) && GetPlayer()->GetTeam() != player->GetTeam()) { SendPartyResult(PARTY_OP_INVITE, memberName, ERR_PLAYER_WRONG_FACTION); return; } if (GetPlayer()->GetInstanceId() != 0 && player->GetInstanceId() != 0 && GetPlayer()->GetInstanceId() != player->GetInstanceId() && GetPlayer()->GetMapId() == player->GetMapId()) { SendPartyResult(PARTY_OP_INVITE, memberName, ERR_TARGET_NOT_IN_INSTANCE_S); return; } // just ignore us if (player->GetInstanceId() != 0 && player->GetDungeonDifficulty() != GetPlayer()->GetDungeonDifficulty()) { SendPartyResult(PARTY_OP_INVITE, memberName, ERR_IGNORING_YOU_S); return; } if (player->GetSocial()->HasIgnore(GetPlayer()->GetGUIDLow())) { SendPartyResult(PARTY_OP_INVITE, memberName, ERR_IGNORING_YOU_S); return; } ObjectGuid invitedGuid = player->GetGUID(); Group* group = GetPlayer()->GetGroup(); if (group && group->isBGGroup()) group = GetPlayer()->GetOriginalGroup(); Group* group2 = player->GetGroup(); if (group2 && group2->isBGGroup()) group2 = player->GetOriginalGroup(); // player already in another group or invited if (group2 || player->GetGroupInvite()) { SendPartyResult(PARTY_OP_INVITE, memberName, ERR_ALREADY_IN_GROUP_S); if (group2) { // tell the player that they were invited but it failed as they were already in a group WorldPacket data(SMSG_GROUP_INVITE, 45); data.WriteBit(0); data.WriteBit(invitedGuid[0]); data.WriteBit(invitedGuid[3]); data.WriteBit(invitedGuid[2]); data.WriteBit(0); // Inverse already in group data.WriteBit(invitedGuid[6]); data.WriteBit(invitedGuid[5]); data.WriteBits(0, 9); // Realm name data.WriteBit(invitedGuid[4]); data.WriteBits(GetPlayer()->GetName().size(), 7); // Inviter name length data.WriteBits(0, 24); // Count 2 data.WriteBit(0); data.WriteBit(invitedGuid[1]); data.WriteBit(invitedGuid[7]); data.FlushBits(); data.WriteByteSeq(invitedGuid[1]); data.WriteByteSeq(invitedGuid[4]); data << int32(getMSTime()); data << int32(0); data << int32(0); data.WriteByteSeq(invitedGuid[6]); data.WriteByteSeq(invitedGuid[0]); data.WriteByteSeq(invitedGuid[2]); data.WriteByteSeq(invitedGuid[3]); // for count2 { int32(0) } data.WriteByteSeq(invitedGuid[5]); // data.append(realm name); data.WriteByteSeq(invitedGuid[7]); data.WriteString(GetPlayer()->GetName()); // inviter name data << int32(0); player->GetSession()->SendPacket(&data); } return; } if (group) { // not have permissions for invite if (!group->IsLeader(GetPlayer()->GetGUID()) && !group->IsAssistant(GetPlayer()->GetGUID())) { SendPartyResult(PARTY_OP_INVITE, "", ERR_NOT_LEADER); return; } // not have place if (group->IsFull()) { SendPartyResult(PARTY_OP_INVITE, "", ERR_GROUP_FULL); return; } } // ok, but group not exist, start a new group // but don't create and save the group to the DB until // at least one person joins if (!group) { group = new Group; // new group: if can't add then delete if (!group->AddLeaderInvite(GetPlayer())) { delete group; return; } if (!group->AddInvite(player)) { delete group; return; } } else { // already existed group: if can't add then just leave if (!group->AddInvite(player)) { return; } } // ok, we do it WorldPacket data(SMSG_GROUP_INVITE, 45); data.WriteBit(0); data.WriteBit(invitedGuid[0]); data.WriteBit(invitedGuid[3]); data.WriteBit(invitedGuid[2]); data.WriteBit(1); // Inverse already in group data.WriteBit(invitedGuid[6]); data.WriteBit(invitedGuid[5]); data.WriteBits(0, 9); // Realm name data.WriteBit(invitedGuid[4]); data.WriteBits(GetPlayer()->GetName().size(), 7); // Inviter name length data.WriteBits(0, 24); // Count 2 data.WriteBit(0); data.WriteBit(invitedGuid[1]); data.WriteBit(invitedGuid[7]); data.FlushBits(); data.WriteByteSeq(invitedGuid[1]); data.WriteByteSeq(invitedGuid[4]); data << int32(getMSTime()); data << int32(0); data << int32(0); data.WriteByteSeq(invitedGuid[6]); data.WriteByteSeq(invitedGuid[0]); data.WriteByteSeq(invitedGuid[2]); data.WriteByteSeq(invitedGuid[3]); // for count2 { int32(0) } data.WriteByteSeq(invitedGuid[5]); // data.append(realm name); data.WriteByteSeq(invitedGuid[7]); data.WriteString(GetPlayer()->GetName()); data << int32(0); player->GetSession()->SendPacket(&data); SendPartyResult(PARTY_OP_INVITE, memberName, ERR_PARTY_RESULT_OK); }
void WorldSession::HandleGroupInviteOpcode(WorldPacket & recv_data) { std::string membername; recv_data >> membername; recv_data.read_skip<uint32>(); // attempt add selected player // cheating if (!normalizePlayerName(membername)) { SendPartyResult(PARTY_OP_INVITE, membername, ERR_BAD_PLAYER_NAME_S); return; } Player *player = sObjectMgr->GetPlayer(membername.c_str()); // no player if (!player) { SendPartyResult(PARTY_OP_INVITE, membername, ERR_BAD_PLAYER_NAME_S); return; } // restrict invite to GMs if (!sWorld->getBoolConfig(CONFIG_ALLOW_GM_GROUP) && !GetPlayer()->isGameMaster() && player->isGameMaster()) return; // can't group with if (!sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GROUP) && GetPlayer()->GetTeam() != player->GetTeam()) { SendPartyResult(PARTY_OP_INVITE, membername, ERR_PLAYER_WRONG_FACTION); return; } if (GetPlayer()->GetInstanceId() != 0 && player->GetInstanceId() != 0 && GetPlayer()->GetInstanceId() != player->GetInstanceId() && GetPlayer()->GetMapId() == player->GetMapId()) { SendPartyResult(PARTY_OP_INVITE, membername, ERR_TARGET_NOT_IN_INSTANCE_S); return; } // just ignore us if (player->GetInstanceId() != 0 && player->GetDungeonDifficulty() != GetPlayer()->GetDungeonDifficulty()) { SendPartyResult(PARTY_OP_INVITE, membername, ERR_IGNORING_YOU_S); return; } if (player->GetSocial()->HasIgnore(GetPlayer()->GetGUIDLow())) { SendPartyResult(PARTY_OP_INVITE, membername, ERR_IGNORING_YOU_S); return; } Group *group = GetPlayer()->GetGroup(); if (group && group->isBGGroup()) group = GetPlayer()->GetOriginalGroup(); Group *group2 = player->GetGroup(); if (group2 && group2->isBGGroup()) group2 = player->GetOriginalGroup(); // player already in another group or invited if (group2 || player->GetGroupInvite()) { SendPartyResult(PARTY_OP_INVITE, membername, ERR_ALREADY_IN_GROUP_S); if (group2) { // tell the player that they were invited but it failed as they were already in a group WorldPacket data(SMSG_GROUP_INVITE, 10); // guess size data << uint8(0); // invited/already in group flag data << GetPlayer()->GetName(); // max len 48 data << uint32(0); // unk data << uint8(0); // count data << uint32(0); // unk player->GetSession()->SendPacket(&data); } return; } if (group) { // not have permissions for invite if (!group->IsLeader(GetPlayer()->GetGUID()) && !group->IsAssistant(GetPlayer()->GetGUID())) { SendPartyResult(PARTY_OP_INVITE, "", ERR_NOT_LEADER); return; } // not have place if (group->IsFull()) { SendPartyResult(PARTY_OP_INVITE, "", ERR_GROUP_FULL); return; } } // ok, but group not exist, start a new group // but don't create and save the group to the DB until // at least one person joins if (!group) { group = new Group; // new group: if can't add then delete if (!group->AddLeaderInvite(GetPlayer())) { delete group; return; } if (!group->AddInvite(player)) { delete group; return; } } else { // already existed group: if can't add then just leave if (!group->AddInvite(player)) { return; } } // ok, we do it WorldPacket data(SMSG_GROUP_INVITE, 10); // guess size data << uint8(1); // invited/already in group flag data << GetPlayer()->GetName(); // max len 48 data << uint32(0); // unk data << uint8(0); // count data << uint32(0); // unk player->GetSession()->SendPacket(&data); SendPartyResult(PARTY_OP_INVITE, membername, ERR_PARTY_RESULT_OK); }
//Teleport to Player bool ChatHandler::HandleAppearCommand(const char* args) { Player* target; uint64 target_guid; std::string target_name; if (!extractPlayerTarget((char*)args, &target, &target_guid, &target_name)) return false; Player* _player = m_session->GetPlayer(); if (target == _player || target_guid == _player->GetGUID()) { SendSysMessage(LANG_CANT_TELEPORT_SELF); SetSentErrorMessage(true); return false; } if (target) { // check online security if (HasLowerSecurity(target, 0)) return false; std::string chrNameLink = playerLink(target_name); Map* cMap = target->GetMap(); if (cMap->IsBattlegroundOrArena()) { // only allow if gm mode is on if (!_player->isGameMaster()) { PSendSysMessage(LANG_CANNOT_GO_TO_BG_GM, chrNameLink.c_str()); SetSentErrorMessage(true); return false; } // if both players are in different bgs else if (_player->GetBattlegroundId() && _player->GetBattlegroundId() != target->GetBattlegroundId()) _player->LeaveBattleground(false); // Note: should be changed so _player gets no Deserter debuff // all's well, set bg id // when porting out from the bg, it will be reset to 0 _player->SetBattlegroundId(target->GetBattlegroundId(), target->GetBattlegroundTypeId()); // remember current position as entry point for return at bg end teleportation if (!_player->GetMap()->IsBattlegroundOrArena()) _player->SetBattlegroundEntryPoint(); } else if (cMap->IsDungeon()) { // we have to go to instance, and can go to player only if: // 1) we are in his group (either as leader or as member) // 2) we are not bound to any group and have GM mode on if (_player->GetGroup()) { // we are in group, we can go only if we are in the player group if (_player->GetGroup() != target->GetGroup()) { PSendSysMessage(LANG_CANNOT_GO_TO_INST_PARTY, chrNameLink.c_str()); SetSentErrorMessage(true); return false; } } else { // we are not in group, let's verify our GM mode if (!_player->isGameMaster()) { PSendSysMessage(LANG_CANNOT_GO_TO_INST_GM, chrNameLink.c_str()); SetSentErrorMessage(true); return false; } } // if the player or the player's group is bound to another instance // the player will not be bound to another one InstancePlayerBind* pBind = _player->GetBoundInstance(target->GetMapId(), target->GetDifficulty(cMap->IsRaid())); if (!pBind) { Group* group = _player->GetGroup(); // if no bind exists, create a solo bind InstanceGroupBind* gBind = group ? group->GetBoundInstance(target) : NULL; // if no bind exists, create a solo bind if (!gBind) if (InstanceSave* save = sInstanceSaveMgr->GetInstanceSave(target->GetInstanceId())) _player->BindToInstance(save, !save->CanReset()); } if (cMap->IsRaid()) _player->SetRaidDifficulty(target->GetRaidDifficulty()); else _player->SetDungeonDifficulty(target->GetDungeonDifficulty()); } PSendSysMessage(LANG_APPEARING_AT, chrNameLink.c_str()); // stop flight if need if (_player->isInFlight()) { _player->GetMotionMaster()->MovementExpired(); _player->CleanupAfterTaxiFlight(); } // save only in non-flight case else _player->SaveRecallPosition(); // to point to see at target with same orientation float x, y, z; target->GetContactPoint(_player, x, y, z); _player->TeleportTo(target->GetMapId(), x, y, z, _player->GetAngle(target), TELE_TO_GM_MODE); _player->SetPhaseMask(target->GetPhaseMask(), true); } else { // check offline security if (HasLowerSecurity(NULL, target_guid)) return false; std::string nameLink = playerLink(target_name); PSendSysMessage(LANG_APPEARING_AT, nameLink.c_str()); // to point where player stay (if loaded) float x, y, z, o; uint32 map; bool in_flight; if (!Player::LoadPositionFromDB(map, x, y, z, o, in_flight, target_guid)) return false; // stop flight if need if (_player->isInFlight()) { _player->GetMotionMaster()->MovementExpired(); _player->CleanupAfterTaxiFlight(); } // save only in non-flight case else _player->SaveRecallPosition(); _player->TeleportTo(map, x, y, z, _player->GetOrientation()); } return true; }
//Summon Player bool ChatHandler::HandleSummonCommand(const char* args) { Player* target; uint64 target_guid; std::string target_name; if (!extractPlayerTarget((char*)args, &target, &target_guid, &target_name)) return false; Player* _player = m_session->GetPlayer(); if (target == _player || target_guid == _player->GetGUID()) { PSendSysMessage(LANG_CANT_TELEPORT_SELF); SetSentErrorMessage(true); return false; } if (target) { std::string nameLink = playerLink(target_name); // check online security if (HasLowerSecurity(target, 0)) return false; if (target->IsBeingTeleported()) { PSendSysMessage(LANG_IS_TELEPORTED, nameLink.c_str()); SetSentErrorMessage(true); return false; } Map* map = m_session->GetPlayer()->GetMap(); if (map->IsBattlegroundOrArena()) { // only allow if gm mode is on if (!_player->isGameMaster()) { PSendSysMessage(LANG_CANNOT_GO_TO_BG_GM, nameLink.c_str()); SetSentErrorMessage(true); return false; } // if both players are in different bgs else if (target->GetBattlegroundId() && m_session->GetPlayer()->GetBattlegroundId() != target->GetBattlegroundId()) target->LeaveBattleground(false); // Note: should be changed so target gets no Deserter debuff // all's well, set bg id // when porting out from the bg, it will be reset to 0 target->SetBattlegroundId(m_session->GetPlayer()->GetBattlegroundId(), m_session->GetPlayer()->GetBattlegroundTypeId()); // remember current position as entry point for return at bg end teleportation if (!target->GetMap()->IsBattlegroundOrArena()) target->SetBattlegroundEntryPoint(); } else if (map->IsDungeon()) { Map* cMap = target->GetMap(); if (cMap->Instanceable() && cMap->GetInstanceId() != map->GetInstanceId()) target->UnbindInstance(map->GetInstanceId(), target->GetDungeonDifficulty(), true); // we are in instance, and can summon only player in our group with us as lead if (!m_session->GetPlayer()->GetGroup() || !target->GetGroup() || (target->GetGroup()->GetLeaderGUID() != m_session->GetPlayer()->GetGUID()) || (m_session->GetPlayer()->GetGroup()->GetLeaderGUID() != m_session->GetPlayer()->GetGUID())) // the last check is a bit excessive, but let it be, just in case { PSendSysMessage(LANG_CANNOT_SUMMON_TO_INST, nameLink.c_str()); SetSentErrorMessage(true); return false; } } PSendSysMessage(LANG_SUMMONING, nameLink.c_str(), ""); if (needReportToTarget(target)) ChatHandler(target).PSendSysMessage(LANG_SUMMONED_BY, playerLink(_player->GetName()).c_str()); // stop flight if need if (target->isInFlight()) { target->GetMotionMaster()->MovementExpired(); target->CleanupAfterTaxiFlight(); } // save only in non-flight case else target->SaveRecallPosition(); // before GM float x, y, z; m_session->GetPlayer()->GetClosePoint(x, y, z, target->GetObjectSize()); target->TeleportTo(m_session->GetPlayer()->GetMapId(), x, y, z, target->GetOrientation()); target->SetPhaseMask(m_session->GetPlayer()->GetPhaseMask(), true); } else { // check offline security if (HasLowerSecurity(NULL, target_guid)) return false; std::string nameLink = playerLink(target_name); PSendSysMessage(LANG_SUMMONING, nameLink.c_str(), GetSkyFireString(LANG_OFFLINE)); // in point where GM stay Player::SavePositionInDB(m_session->GetPlayer()->GetMapId(), m_session->GetPlayer()->GetPositionX(), m_session->GetPlayer()->GetPositionY(), m_session->GetPlayer()->GetPositionZ(), m_session->GetPlayer()->GetOrientation(), m_session->GetPlayer()->GetZoneId(), target_guid); } return true; }
MapMgr* InstanceMgr::GetInstance(Object* obj) { Player* plr; Instance* in; InstanceMap::iterator itr; InstanceMap* instancemap; MapInfo* inf = WorldMapInfoStorage.LookupEntry(obj->GetMapId()); // we can *never* teleport to maps without a mapinfo. if(inf == NULL || obj->GetMapId() >= NUM_MAPS) return NULL; if(obj->IsPlayer()) { // players can join instances based on their groups/solo status. plr = TO< Player* >(obj); // single-instance maps never go into the instance set. if(inf->type == INSTANCE_NULL) return m_singleMaps[obj->GetMapId()]; m_mapLock.Acquire(); instancemap = m_instances[obj->GetMapId()]; if(instancemap != NULL) { // check our saved instance id. see if its valid, and if we can join before trying to find one. itr = instancemap->find(obj->GetInstanceID()); if(itr != instancemap->end()) { if(itr->second->m_mapMgr == NULL) { itr->second->m_mapMgr = _CreateInstance(itr->second); } if(itr->second->m_mapMgr) { m_mapLock.Release(); return itr->second->m_mapMgr; } } // iterate over our instances, and see if any of them are owned/joinable by him. for(itr = instancemap->begin(); itr != instancemap->end();) { in = itr->second; ++itr; uint32 difficulty; if(in->m_mapInfo->type == INSTANCE_RAID) difficulty = plr->GetRaidDifficulty(); else difficulty = plr->GetDungeonDifficulty(); if(in->m_difficulty == difficulty && PlayerOwnsInstance(in, plr)) { // this is our instance. if(in->m_mapMgr == NULL) { /*if(plr->m_TeleportState == 1) { // the player is loading. boot him out to the entry point, we don't want to spam useless instances on startup. m_mapLock.Release(); return NULL; }*/ // create the actual instance. in->m_mapMgr = _CreateInstance(in); m_mapLock.Release(); return in->m_mapMgr; } else { // instance is already created. m_mapLock.Release(); return in->m_mapMgr; } } } } // if we're here, it means there are no instances on that map, or none of the instances on that map are joinable // by this player. m_mapLock.Release(); return NULL; } else { // units are *always* limited to their set instance ids. if(inf->type == INSTANCE_NULL) return m_singleMaps[obj->GetMapId()]; m_mapLock.Acquire(); instancemap = m_instances[obj->GetMapId()]; if(instancemap) { itr = instancemap->find(obj->GetInstanceID()); if(itr != instancemap->end()) { // we never create instances just for units. m_mapLock.Release(); return itr->second->m_mapMgr; } } // instance is non-existent (shouldn't really happen for units...) m_mapLock.Release(); return NULL; } }
void WorldSession::HandleGroupInviteOpcode( WorldPacket & recv_data ) { std::string membername; recv_data >> membername; // attempt add selected player // cheating if (!normalizePlayerName(membername)) { SendPartyResult(PARTY_OP_INVITE, membername, PARTY_RESULT_CANT_FIND_TARGET); return; } Player *player = sObjectMgr.GetPlayer(membername.c_str()); // no player if (!player) { SendPartyResult(PARTY_OP_INVITE, membername, PARTY_RESULT_CANT_FIND_TARGET); return; } // restrict invite to GMs if (!sWorld.getConfig(CONFIG_ALLOW_GM_GROUP) && !GetPlayer()->isGameMaster() && player->isGameMaster()) { SendPartyResult(PARTY_OP_INVITE, membername, PARTY_RESULT_CANT_FIND_TARGET); return; } // can't group with if (!sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GROUP) && GetPlayer()->GetTeam() != player->GetTeam()) { SendPartyResult(PARTY_OP_INVITE, membername, PARTY_RESULT_TARGET_UNFRIENDLY); return; } if (GetPlayer()->GetInstanceId() != 0 && player->GetInstanceId() != 0 && GetPlayer()->GetInstanceId() != player->GetInstanceId() && GetPlayer()->GetMapId() == player->GetMapId()) { SendPartyResult(PARTY_OP_INVITE, membername, PARTY_RESULT_NOT_IN_YOUR_INSTANCE); return; } // just ignore us if (player->GetInstanceId() != 0 && player->GetDungeonDifficulty() != GetPlayer()->GetDungeonDifficulty()) { SendPartyResult(PARTY_OP_INVITE, membername, PARTY_RESULT_TARGET_IGNORE_YOU); return; } if (player->GetSocial()->HasIgnore(GetPlayer()->GetGUIDLow())) { SendPartyResult(PARTY_OP_INVITE, membername, PARTY_RESULT_TARGET_IGNORE_YOU); return; } Group *group = GetPlayer()->GetGroup(); if ( group && group->isBGGroup() ) group = GetPlayer()->GetOriginalGroup(); Group *group2 = player->GetGroup(); if ( group2 && group2->isBGGroup() ) group2 = player->GetOriginalGroup(); // player already in another group or invited if ( group2 || player->GetGroupInvite() ) { SendPartyResult(PARTY_OP_INVITE, membername, PARTY_RESULT_ALREADY_IN_GROUP); return; } if (group) { // not have permissions for invite if (group->isRaidGroup() && !group->IsLeader(GetPlayer()->GetGUID()) && !group->IsAssistant(GetPlayer()->GetGUID())) { SendPartyResult(PARTY_OP_INVITE, "", PARTY_RESULT_YOU_NOT_LEADER); return; } // not have place if (group->IsFull()) { SendPartyResult(PARTY_OP_INVITE, "", PARTY_RESULT_PARTY_FULL); return; } } // ok, but group not exist, start a new group // but don't create and save the group to the DB until // at least one person joins if (!group) { group = new Group; // new group: if can't add then delete if (!group->AddLeaderInvite(GetPlayer())) { delete group; return; } if (!group->AddInvite(player)) { delete group; return; } } else { // already existed group: if can't add then just leave if (!group->AddInvite(player)) { return; } } // ok, we do it WorldPacket data(SMSG_GROUP_INVITE, 10); // guess size data << uint8(1); // ok data << GetPlayer()->GetName(); player->GetSession()->SendPacket(&data); SendPartyResult(PARTY_OP_INVITE, membername, PARTY_RESULT_OK); }
void WorldSession::HandleGroupInviteOpcode(WorldPacket& recvData) { TC_LOG_DEBUG("network", "WORLD: Received CMSG_GROUP_INVITE"); std::string membername; recvData >> membername; recvData.read_skip<uint32>(); // attempt add selected player // cheating if (!normalizePlayerName(membername)) { SendPartyResult(PARTY_OP_INVITE, membername, ERR_BAD_PLAYER_NAME_S); return; } Player* invitingPlayer = GetPlayer(); Player* invitedPlayer = ObjectAccessor::FindPlayerByName(membername); // no player if (!invitedPlayer) { SendPartyResult(PARTY_OP_INVITE, membername, ERR_BAD_PLAYER_NAME_S); return; } // player trying to invite himself (most likely cheating) if (invitedPlayer == invitingPlayer) { SendPartyResult(PARTY_OP_INVITE, membername, ERR_BAD_PLAYER_NAME_S); return; } // restrict invite to GMs if (!sWorld->getBoolConfig(CONFIG_ALLOW_GM_GROUP) && !invitingPlayer->IsGameMaster() && invitedPlayer->IsGameMaster()) { SendPartyResult(PARTY_OP_INVITE, membername, ERR_BAD_PLAYER_NAME_S); return; } // can't group with if (!invitingPlayer->IsGameMaster() && !sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GROUP) && invitingPlayer->GetTeam() != invitedPlayer->GetTeam()) { SendPartyResult(PARTY_OP_INVITE, membername, ERR_PLAYER_WRONG_FACTION); return; } if (invitingPlayer->GetInstanceId() != 0 && invitedPlayer->GetInstanceId() != 0 && invitingPlayer->GetInstanceId() != invitedPlayer->GetInstanceId() && invitingPlayer->GetMapId() == invitedPlayer->GetMapId()) { SendPartyResult(PARTY_OP_INVITE, membername, ERR_TARGET_NOT_IN_INSTANCE_S); return; } // just ignore us if (invitedPlayer->GetInstanceId() != 0 && invitedPlayer->GetDungeonDifficulty() != invitingPlayer->GetDungeonDifficulty()) { SendPartyResult(PARTY_OP_INVITE, membername, ERR_IGNORING_YOU_S); return; } if (invitedPlayer->GetSocial()->HasIgnore(invitingPlayer->GetGUID())) { SendPartyResult(PARTY_OP_INVITE, membername, ERR_IGNORING_YOU_S); return; } if (!invitedPlayer->GetSocial()->HasFriend(invitingPlayer->GetGUID()) && invitingPlayer->getLevel() < sWorld->getIntConfig(CONFIG_PARTY_LEVEL_REQ)) { SendPartyResult(PARTY_OP_INVITE, membername, ERR_INVITE_RESTRICTED); return; } Group* group = invitingPlayer->GetGroup(); if (group && group->isBGGroup()) group = invitingPlayer->GetOriginalGroup(); if (!group) group = invitingPlayer->GetGroupInvite(); Group* group2 = invitedPlayer->GetGroup(); if (group2 && group2->isBGGroup()) group2 = invitedPlayer->GetOriginalGroup(); // player already in another group or invited if (group2 || invitedPlayer->GetGroupInvite()) { SendPartyResult(PARTY_OP_INVITE, membername, ERR_ALREADY_IN_GROUP_S); if (group2) { // tell the player that they were invited but it failed as they were already in a group WorldPacket data(SMSG_GROUP_INVITE, 10); // guess size data << uint8(0); // invited/already in group flag data << invitingPlayer->GetName(); // max len 48 data << uint32(0); // unk data << uint8(0); // count data << uint32(0); // unk invitedPlayer->SendDirectMessage(&data); } return; } if (group) { // not have permissions for invite if (!group->IsLeader(invitingPlayer->GetGUID()) && !group->IsAssistant(invitingPlayer->GetGUID())) { if (group->IsCreated()) SendPartyResult(PARTY_OP_INVITE, "", ERR_NOT_LEADER); return; } // not have place if (group->IsFull()) { SendPartyResult(PARTY_OP_INVITE, "", ERR_GROUP_FULL); return; } } // ok, but group not exist, start a new group // but don't create and save the group to the DB until // at least one person joins if (!group) { group = new Group(); // new group: if can't add then delete if (!group->AddLeaderInvite(invitingPlayer)) { delete group; return; } if (!group->AddInvite(invitedPlayer)) { group->RemoveAllInvites(); delete group; return; } } else { // already existed group: if can't add then just leave if (!group->AddInvite(invitedPlayer)) { return; } } // ok, we do it WorldPacket data(SMSG_GROUP_INVITE, 10); // guess size data << uint8(1); // invited/already in group flag data << invitingPlayer->GetName(); // max len 48 data << uint32(0); // unk data << uint8(0); // count data << uint32(0); // unk invitedPlayer->SendDirectMessage(&data); SendPartyResult(PARTY_OP_INVITE, membername, ERR_PARTY_RESULT_OK); }
void WorldSession::HandleGroupInviteOpcode(WorldPacket& recvData) { time_t now = time(NULL); if (now - timeLastGroupInviteCommand < 5) return; else timeLastGroupInviteCommand = now; ObjectGuid crossRealmGuid; // unused recvData.read_skip<uint32>(); // Non-zero in cross realm invites recvData.read_skip<uint32>(); // Always 0 recvData.read_skip<uint8>(); // Unknown std::string realmName, memberName; realmName = ""; memberName = ""; crossRealmGuid[5] = recvData.ReadBit(); uint8 nameLen = recvData.ReadBits(9); crossRealmGuid[2] = recvData.ReadBit(); crossRealmGuid[1] = recvData.ReadBit(); crossRealmGuid[7] = recvData.ReadBit(); crossRealmGuid[4] = recvData.ReadBit(); crossRealmGuid[3] = recvData.ReadBit(); uint8 realmLen = recvData.ReadBits(9); crossRealmGuid[0] = recvData.ReadBit(); crossRealmGuid[6] = recvData.ReadBit(); recvData.FlushBits(); recvData.ReadByteSeq(crossRealmGuid[0]); recvData.ReadByteSeq(crossRealmGuid[4]); realmName = recvData.ReadString(realmLen); recvData.ReadByteSeq(crossRealmGuid[5]); recvData.ReadByteSeq(crossRealmGuid[6]); memberName = recvData.ReadString(nameLen); recvData.ReadByteSeq(crossRealmGuid[1]); recvData.ReadByteSeq(crossRealmGuid[7]); recvData.ReadByteSeq(crossRealmGuid[3]); recvData.ReadByteSeq(crossRealmGuid[2]); // Attempt to add selected player. auto delimeter_pos = memberName.find("-"); if (delimeter_pos > 0) memberName = memberName.substr(0, delimeter_pos); // cheating if (!normalizePlayerName(memberName)) { SendPartyResult(PARTY_OP_INVITE, memberName, ERR_BAD_PLAYER_NAME_S); return; } Player* player = sObjectAccessor->FindPlayerByName(memberName.c_str()); // no player if (!player) { SendPartyResult(PARTY_OP_INVITE, memberName, ERR_BAD_PLAYER_NAME_S); return; } // restrict invite to GMs if (!sWorld->getBoolConfig(CONFIG_ALLOW_GM_GROUP) && !GetPlayer()->isGameMaster() && player->isGameMaster()) { SendPartyResult(PARTY_OP_INVITE, memberName, ERR_BAD_PLAYER_NAME_S); return; } // can't group with if (!GetPlayer()->isGameMaster() && !sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GROUP) && GetPlayer()->GetTeam() != player->GetTeam()) { SendPartyResult(PARTY_OP_INVITE, memberName, ERR_PLAYER_WRONG_FACTION); return; } if (GetPlayer()->GetInstanceId() != 0 && player->GetInstanceId() != 0 && GetPlayer()->GetInstanceId() != player->GetInstanceId() && GetPlayer()->GetMapId() == player->GetMapId()) { SendPartyResult(PARTY_OP_INVITE, memberName, ERR_TARGET_NOT_IN_INSTANCE_S); return; } // just ignore us if (player->GetInstanceId() != 0 && player->GetDungeonDifficulty() != GetPlayer()->GetDungeonDifficulty()) { SendPartyResult(PARTY_OP_INVITE, memberName, ERR_IGNORING_YOU_S); return; } if (player->GetSocial()->HasIgnore(GetPlayer()->GetGUIDLow())) { SendPartyResult(PARTY_OP_INVITE, memberName, ERR_IGNORING_YOU_S); return; } Group* group = GetPlayer()->GetGroup(); if (group && group->isBGGroup()) group = GetPlayer()->GetOriginalGroup(); Group* group2 = player->GetGroup(); if (group2 && group2->isBGGroup()) group2 = player->GetOriginalGroup(); // player already in another group or invited if (group2 || player->GetGroupInvite()) { SendPartyResult(PARTY_OP_INVITE, memberName, ERR_ALREADY_IN_GROUP_S); if (group2) player->GetSession()->SendGroupInviteNotification(GetPlayer()->GetName(), true); return; } if (group) { // not have permissions for invite if (!group->IsLeader(GetPlayer()->GetGUID()) && !group->IsAssistant(GetPlayer()->GetGUID()) && !(group->GetGroupType() & GROUPTYPE_EVERYONE_IS_ASSISTANT)) { SendPartyResult(PARTY_OP_INVITE, "", ERR_NOT_LEADER); return; } // not have place if (group->IsFull()) { SendPartyResult(PARTY_OP_INVITE, "", ERR_GROUP_FULL); return; } } // ok, but group not exist, start a new group // but don't create and save the group to the DB until // at least one person joins if (!group) { group = new Group; // new group: if can't add then delete if (!group->AddLeaderInvite(GetPlayer())) { delete group; return; } if (!group->AddInvite(player)) { delete group; return; } } else { // already existed group: if can't add then just leave if (!group->AddInvite(player)) { return; } } // ok, we do it player->GetSession()->SendGroupInviteNotification(GetPlayer()->GetName(), false); SendPartyResult(PARTY_OP_INVITE, memberName, ERR_PARTY_RESULT_OK); }