void WorldSession::HandleRequestJoinUpdates(WorldPacket& /*recvData*/) { TC_LOG_DEBUG("network", "WORLD: Received CMSG_GROUP_REQUEST_JOIN_UPDATES "); Group * grp = GetPlayer()->GetGroup(); if(grp) { WorldPacket data(SMSG_REAL_GROUP_UPDATE,13); data << uint8(grp->GetGroupType()); data << uint32(grp->GetMembersCount()); if(grp->GetMembersCount() > 2) //group is already formed, send the latest member guid { Group::MemberSlotList::const_iterator lastMember = --grp->GetMemberSlots().end(); data << uint64(lastMember->guid); } else // group has just formed, send the other player guid { Group::MemberSlotList::const_iterator member = grp->GetMemberSlots().begin(); if(member->guid == GetPlayer()->GetGUID()) ++member; data << uint64(member->guid); } SendPacket(&data); } }
void WorldSession::HandlePartyAssignmentOpcode(WorldPacket& recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_GROUP_ASSIGNMENT"); Group* group = GetPlayer()->GetGroup(); if (!group) return; uint64 senderGuid = GetPlayer()->GetGUID(); if (!group->IsLeader(senderGuid) && !group->IsAssistant(senderGuid) && !(group->GetGroupType() & GROUPTYPE_EVERYONE_IS_ASSISTANT)) return; uint8 assignment; bool apply; ObjectGuid guid; recvData >> assignment; recvData.read_skip<uint8>(); // Unknown. guid[0] = recvData.ReadBit(); guid[5] = recvData.ReadBit(); guid[6] = recvData.ReadBit(); guid[7] = recvData.ReadBit(); guid[3] = recvData.ReadBit(); guid[1] = recvData.ReadBit(); guid[2] = recvData.ReadBit(); apply = recvData.ReadBit(); guid[4] = recvData.ReadBit(); recvData.FlushBits(); uint8 byteOrder[8] = { 4, 3, 1, 5, 2, 6, 7, 0 }; recvData.ReadBytesSeq(guid, byteOrder); switch (assignment) { case GROUP_ASSIGN_MAINASSIST: group->RemoveUniqueGroupMemberFlag(MEMBER_FLAG_MAINASSIST); group->SetGroupMemberFlag(guid, apply, MEMBER_FLAG_MAINASSIST); break; case GROUP_ASSIGN_MAINTANK: group->RemoveUniqueGroupMemberFlag(MEMBER_FLAG_MAINTANK); // Remove main assist flag from current if any. group->SetGroupMemberFlag(guid, apply, MEMBER_FLAG_MAINTANK); break; default: break; } group->SendUpdate(); }
void WorldSession::HandleGroupRequestJoinUpdates(WorldPacket& /*recvData*/) { Group* group = GetPlayer()->GetGroup(); if (!group) return; WorldPacket data(SMSG_REAL_GROUP_UPDATE, 1 + 4 + 8); data << uint8(group->GetGroupType()); data << uint32(group->GetMembersCount() - 1); data << uint64(group->GetLeaderGUID()); SendPacket(&data); }
////////////////////////////////////////////////////////////////////////////////////////// ///This function handles CMSG_GROUP_DISBAND: ////////////////////////////////////////////////////////////////////////////////////////// void WorldSession::HandleGroupDisbandOpcode(WorldPacket & recv_data) { // this is actually leaving a party, disband is not possible anymore CHECK_INWORLD_RETURN; Group* pGroup = _player->GetGroup(); if(pGroup == NULL) return; // cant leave a battleground group (blizzlike 3.3.3) if(pGroup->GetGroupType() & GROUP_TYPE_BG) return; pGroup->RemovePlayer(_player->m_playerInfo); }
////////////////////////////////////////////////////////////////////////////////////////// ///This function handles CMSG_GROUP_DISBAND: ////////////////////////////////////////////////////////////////////////////////////////// void WorldSession::HandleGroupDisbandOpcode( WorldPacket & recv_data ) { if(!_player->IsInWorld()) { return; } Group* pGroup = _player->GetGroup(); if(!pGroup) { return; } // cant leave a battleground group (blizzlike 3.3.3) if( pGroup->GetGroupType() & GROUP_TYPE_BG ) return; //pGroup->Disband(); pGroup->RemovePlayer(_player->m_playerInfo); }
void WorldSession::HandleGroupChangeSubGroupOpcode(WorldPacket& recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_GROUP_CHANGE_SUB_GROUP"); // we will get correct pointer for group here, so we don't have to check if group is BG raid Group* group = GetPlayer()->GetGroup(); if (!group) return; time_t now = time(NULL); if (now - timeLastChangeSubGroupCommand < 2) return; else timeLastChangeSubGroupCommand = now; ObjectGuid guid; uint8 groupNr, unk; recvData >> unk >> groupNr; uint8 bitsOrder[8] = { 1, 3, 7, 2, 0, 5, 4, 6 }; recvData.ReadBitInOrder(guid, bitsOrder); recvData.FlushBits(); uint8 bytesOrder[8] = { 7, 0, 2, 4, 5, 3, 6, 1 }; recvData.ReadBytesSeq(guid, bytesOrder); if (groupNr >= MAX_RAID_SUBGROUPS) return; uint64 senderGuid = GetPlayer()->GetGUID(); if (!group->IsLeader(senderGuid) && !group->IsAssistant(senderGuid) && !(group->GetGroupType() & GROUPTYPE_EVERYONE_IS_ASSISTANT)) return; if (!group->HasFreeSlotSubGroup(groupNr)) return; if (Player* movedPlayer = sObjectAccessor->FindPlayer(guid)) group->ChangeMembersGroup(guid, groupNr); }
uint32 InstanceMgr::PreTeleport(uint32 mapid, Player* plr, uint32 instanceid) { // preteleport is where all the magic happens :P instance creation, etc. MapInfo* inf = WorldMapInfoStorage.LookupEntry(mapid); Group* pGroup; InstanceMap* instancemap; Instance* in; if(inf == NULL || mapid >= NUM_MAPS) return INSTANCE_ABORT_NOT_FOUND; // main continent check. if(inf->type == INSTANCE_NULL) { // this will be useful when clustering comes into play. // we can check if the destination world server is online or not and then cancel them before they load. return (m_singleMaps[mapid] != NULL) ? INSTANCE_OK : INSTANCE_ABORT_NOT_FOUND; } // shouldn't happen if(inf->type == INSTANCE_BATTLEGROUND) return INSTANCE_ABORT_NOT_FOUND; pGroup = plr->GetGroup(); // players without groups cannot enter raids and heroic instances if(pGroup == NULL && inf->type == INSTANCE_RAID && !plr->TriggerpassCheat) return INSTANCE_ABORT_NOT_IN_RAID_GROUP; if(pGroup == NULL && (inf->type == INSTANCE_NONRAID && plr->iInstanceType == MODE_HEROIC) && !plr->TriggerpassCheat) return INSTANCE_ABORT_NOT_IN_RAID_GROUP; // players without raid groups cannot enter raid instances if(pGroup != NULL && pGroup->GetGroupType() != GROUP_TYPE_RAID && inf->type == INSTANCE_RAID && !plr->TriggerpassCheat) return INSTANCE_ABORT_NOT_IN_RAID_GROUP; // We deny transfer if we requested a heroic instance of a map that has no heroic mode // We are trying to enter into a non-multi instance with a heroic group, downscaling if(inf->type == INSTANCE_NONRAID && plr->GetDungeonDifficulty() == MODE_HEROIC) { plr->SetDungeonDifficulty(MODE_NORMAL); plr->SendDungeonDifficulty(); Group* grp = plr->GetGroup(); if(grp != NULL) grp->SetDungeonDifficulty(MODE_NORMAL); } // if it's not a normal / 10men normal then check if we even have this mode if(inf->type == INSTANCE_RAID && plr->GetRaidDifficulty() != MODE_NORMAL_10MEN) { uint32 newtype = 0; if(!inf->HasDifficulty(plr->GetRaidDifficulty())) { // no it doesn't so we will downscale it /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // This part is totally speculative, if you know how this is done actually then do change it // switch(plr->GetRaidDifficulty()) { case MODE_NORMAL_25MEN: case MODE_HEROIC_10MEN: { newtype = MODE_NORMAL_10MEN; break; } case MODE_HEROIC_25MEN: { newtype = MODE_NORMAL_25MEN; break; } } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // check if we have this mode if(!inf->HasDifficulty(newtype)) { //appearantly we don't so we set to 10men normal, which is the default for old raids too //regardless of their playerlimit newtype = MODE_NORMAL_10MEN; } // Setting the new mode on us and our group if(plr->GetRaidDifficulty() != newtype) { plr->SetRaidDifficulty(newtype); plr->SendRaidDifficulty(); Group* grp = plr->GetGroup(); if(grp != NULL) grp->SetRaidDifficulty(newtype); } } } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // If we are here, it means: // 1.) We're a simple non-raid and non-heroic dungeon // 2.) We're a multi-dungeon set to heroic and we are in a group // 3.) We're a raid, and we are in a raid group // 4.) We're a raid, we are in a raid group, and we have the right mode set // // So, first we have to check if they have an instance on this map already, if so, allow them to teleport to that. // Otherwise, we will try to create them a new one. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// m_mapLock.Acquire(); instancemap = m_instances[mapid]; // If there are no instances of this map yet, we need to create the map if(instancemap == NULL) { if(instanceid != 0) { m_mapLock.Release(); return INSTANCE_ABORT_NOT_FOUND; } m_instances[mapid] = new InstanceMap; instancemap = m_instances[mapid]; } else { InstanceMap::iterator itr; // this is the case when we enter an already existing instance ( with summons for example ) if(instanceid != 0) { itr = instancemap->find(instanceid); if(itr != instancemap->end()) { in = itr->second; if(!CHECK_INSTANCE_GROUP(in, pGroup)) { // Another group is already playing in this instance of the dungeon... m_mapLock.Release(); sChatHandler.SystemMessageToPlr(plr, "Another group is already inside this instance of the dungeon."); return INSTANCE_ABORT_NOT_IN_RAID_GROUP; } // Try to add instance ID to player plr->SetPersistentInstanceId(in); // Set current group if(pGroup) in->m_creatorGroup = pGroup->GetID(); m_mapLock.Release(); return INSTANCE_OK; } else { m_mapLock.Release(); return INSTANCE_ABORT_NOT_FOUND; } } else // this is the case when we enter the normal way (e.g. we enter thru the portal ) { in = NULL; if(pGroup != NULL) // we are in a group { uint32 grpdiff; // We want to use the raid difficulty for raids, and dungeon difficulty for dungeons if(inf->type == INSTANCE_RAID) grpdiff = pGroup->m_raiddifficulty; else grpdiff = pGroup->m_difficulty; if((inf->type == INSTANCE_MULTIMODE && grpdiff == MODE_HEROIC) || inf->type == INSTANCE_RAID) { // This is the case when we don't have this map on this difficulty saved yet for the player entering if(plr->GetPersistentInstanceId(mapid, grpdiff) == 0) { // The group has this instance saved already so we will use it if(pGroup->m_instanceIds[mapid][ grpdiff ] != 0) { in = sInstanceMgr.GetInstanceByIds(mapid, pGroup->m_instanceIds[mapid][ grpdiff ]); } else if(sWorld.instance_TakeGroupLeaderID) { PlayerInfo* pLeaderInfo = pGroup->GetLeader(); if(pLeaderInfo) { pLeaderInfo->savedInstanceIdsLock.Acquire(); PlayerInstanceMap::iterator itrLeader = pLeaderInfo->savedInstanceIds[ grpdiff ].find(mapid); if(itrLeader != pLeaderInfo->savedInstanceIds[ grpdiff ].end()) { in = sInstanceMgr.GetInstanceByIds(mapid, (*itrLeader).second); } pLeaderInfo->savedInstanceIdsLock.Release(); } } } // If we have it saved to the player then use that if(in == NULL && plr->GetPersistentInstanceId(mapid, grpdiff) != 0) { in = sInstanceMgr.GetInstanceByIds(mapid, plr->GetPersistentInstanceId(mapid, grpdiff)); } } else { if(pGroup->m_instanceIds[mapid][ grpdiff ] != 0) { in = sInstanceMgr.GetInstanceByIds(mapid, pGroup->m_instanceIds[mapid][ grpdiff ]); } } } if(in == NULL) { // We are not in a group, so we will look for an instance that we own and has the right difficulty uint32 diff; if(inf->type == INSTANCE_RAID) diff = plr->GetRaidDifficulty(); else diff = plr->GetDungeonDifficulty(); for(itr = instancemap->begin(); itr != instancemap->end();) { in = itr->second; ++itr; if(in->m_difficulty == diff && PlayerOwnsInstance(in, plr)) break; in = NULL; } } // We've found an instance! if(in != NULL) { m_mapLock.Release(); // check the player count and in combat status. if(in->m_mapMgr) { if(in->m_mapMgr->IsCombatInProgress()) return INSTANCE_ABORT_ENCOUNTER; if(in->m_mapMgr->GetPlayerCount() >= inf->playerlimit) return INSTANCE_ABORT_FULL; } if(!CHECK_INSTANCE_GROUP(in, pGroup)) { // Another group is already playing in this instance of the dungeon... sChatHandler.SystemMessageToPlr(plr, "Another group is already inside this instance of the dungeon."); return INSTANCE_ABORT_NOT_IN_RAID_GROUP; } // Try to add instance ID to player plr->SetPersistentInstanceId(in); // Set current group if(pGroup) in->m_creatorGroup = pGroup->GetID(); plr->SetInstanceID(in->m_instanceId); // found our instance, allow him in. return INSTANCE_OK; } } } // if we're here, it means we need to create a new instance. in = new Instance; in->m_creation = UNIXTIME; switch(inf->type) { case INSTANCE_NONRAID: case INSTANCE_MULTIMODE: in->m_difficulty = plr->GetDungeonDifficulty(); break; case INSTANCE_RAID: in->m_difficulty = plr->GetRaidDifficulty(); break; } in->m_instanceId = GenerateInstanceID(); in->m_mapId = mapid; in->m_mapInfo = inf; in->m_mapMgr = NULL; // always start off without a map manager, it is created in GetInstance() in->m_isBattleground = false; in->m_persistent = IS_PERSISTENT_INSTANCE(in) && objmgr.m_InstanceBossInfoMap[mapid] == NULL; in->m_creatorGuid = pGroup ? 0 : plr->GetLowGUID(); // creator guid is 0 if its owned by a group. in->m_creatorGroup = pGroup ? pGroup->GetID() : 0; if(sWorld.instance_SlidingExpiration) { if(inf->type == INSTANCE_MULTIMODE && in->m_difficulty == MODE_HEROIC) in->m_expiration = UNIXTIME + TIME_DAY; else in->m_expiration = (inf->type == INSTANCE_NONRAID || (inf->type == INSTANCE_MULTIMODE && in->m_difficulty == MODE_NORMAL)) ? 0 : UNIXTIME + inf->cooldown; } else { if(inf->type == INSTANCE_MULTIMODE && in->m_difficulty >= MODE_HEROIC) { in->m_expiration = UNIXTIME - (UNIXTIME % TIME_DAY) + ((UNIXTIME % TIME_DAY) > (sWorld.instance_DailyHeroicInstanceResetHour * TIME_HOUR) ? 82800 : -3600) + ((sWorld.instance_DailyHeroicInstanceResetHour - sWorld.GMTTimeZone) * TIME_HOUR); } else if(IS_PERSISTENT_INSTANCE(in)) { if(m_nextInstanceReset[in->m_mapId] == 0) { m_nextInstanceReset[in->m_mapId] = UNIXTIME - (UNIXTIME % TIME_DAY) - ((sWorld.GMTTimeZone + 1) * TIME_HOUR) + (in->m_mapInfo->cooldown == 0 ? TIME_DAY : in->m_mapInfo->cooldown); CharacterDatabase.Execute("DELETE FROM server_settings WHERE setting_id LIKE 'next_instance_reset_%u';", in->m_mapId); CharacterDatabase.Execute("INSERT INTO server_settings VALUES ('next_instance_reset_%u', '%u')", in->m_mapId, m_nextInstanceReset[in->m_mapId]); } if(m_nextInstanceReset[in->m_mapId] + (TIME_MINUTE * 15) < UNIXTIME) { do { time_t tmp = m_nextInstanceReset[in->m_mapId]; if(tmp + (TIME_MINUTE * 15) < UNIXTIME) m_nextInstanceReset[in->m_mapId] = tmp + (in->m_mapInfo->cooldown == 0 ? TIME_DAY : in->m_mapInfo->cooldown); } while(m_nextInstanceReset[in->m_mapId] + (TIME_MINUTE * 15) < UNIXTIME); CharacterDatabase.Execute("DELETE FROM server_settings WHERE setting_id LIKE 'next_instance_reset_%u';", in->m_mapId); CharacterDatabase.Execute("INSERT INTO server_settings VALUES ('next_instance_reset_%u', '%u')", in->m_mapId, m_nextInstanceReset[in->m_mapId]); } in->m_expiration = m_nextInstanceReset[in->m_mapId]; } else { in->m_expiration = (inf->type == INSTANCE_NONRAID || (inf->type == INSTANCE_MULTIMODE && in->m_difficulty == MODE_NORMAL)) ? 0 : UNIXTIME + inf->cooldown; } } plr->SetInstanceID(in->m_instanceId); Log.Debug("InstanceMgr", "Creating instance for player %u and group %u on map %u. (%u)", in->m_creatorGuid, in->m_creatorGroup, in->m_mapId, in->m_instanceId); // save our new instance to the database. in->SaveToDB(); // apply it in the instance map instancemap->insert(InstanceMap::value_type(in->m_instanceId, in)); // Try to add instance ID to player plr->SetPersistentInstanceId(in); // instance created ok, i guess? return the ok for him to transport. m_mapLock.Release(); return INSTANCE_OK; }
////////////////////////////////////////////////////////////// /// This function handles CMSG_GROUP_INVITE ////////////////////////////////////////////////////////////// void WorldSession::HandleGroupInviteOpcode( WorldPacket & recv_data ) { if(!_player->IsInWorld()) return; CHECK_PACKET_SIZE(recv_data, 1); WorldPacket data(100); std::string membername; Player * player = NULL; Group *group = NULL; recv_data >> membername; if(_player->HasBeenInvited())return; player = objmgr.GetPlayer(membername.c_str(), false); if ( player == NULL) { SendPartyCommandResult(_player, 0, membername, ERR_PARTY_CANNOT_FIND); return; } if (player == _player) { return; } if ( _player->InGroup() && !_player->IsGroupLeader() ) { SendPartyCommandResult(_player, 0, "", ERR_PARTY_YOU_ARE_NOT_LEADER); return; } group = _player->GetGroup(); if ( group != NULL ) { if (group->IsFull()) { SendPartyCommandResult(_player, 0, "", ERR_PARTY_IS_FULL); return; } } if ( player->InGroup() ) { SendPartyCommandResult(_player, player->GetGroup()->GetGroupType(), membername, ERR_PARTY_ALREADY_IN_GROUP); return; } if(player->GetTeam()!=_player->GetTeam() && _player->GetSession()->GetPermissionCount() == 0) { SendPartyCommandResult(_player, 0, membername, ERR_PARTY_WRONG_FACTION); return; } if ( player->HasBeenInvited() ) { SendPartyCommandResult(_player, 0, membername, ERR_PARTY_ALREADY_IN_GROUP); return; } if( player->Social_IsIgnoring( _player->GetLowGUID() ) ) { SendPartyCommandResult(_player, 0, membername, ERR_PARTY_IS_IGNORING_YOU); return; } // 16/08/06 - change to guid to prevent very unlikely event of a crash in deny, etc _player->SetInviter(_player->GetLowGUID());//bugfix if player invtied 2 people-> he can be in 2 parties data.SetOpcode(SMSG_GROUP_INVITE); data << GetPlayer()->GetName(); player->GetSession()->SendPacket(&data); uint32 gtype = 0; if(group) gtype = group->GetGroupType(); SendPartyCommandResult(_player, gtype, membername, ERR_PARTY_NO_ERROR); // 16/08/06 - change to guid to prevent very unlikely event of a crash in deny, etc player->SetInviter(_player->GetLowGUID()); }
void WorldSession::HandleMessagechatOpcode(WorldPacket & recv_data) { CHECK_INWORLD_RETURN CHECK_PACKET_SIZE(recv_data, 9); WorldPacket* data = NULL; uint32 type; int32 lang; const char* pMisc = NULL; const char* pMsg = NULL; recv_data >> type; recv_data >> lang; if(lang >= NUM_LANGUAGES) return; if(GetPlayer()->IsBanned()) { GetPlayer()->BroadcastMessage("You cannot do that when banned."); return; } // Flood protection if(lang != -1 && !GetPermissionCount() && sWorld.flood_lines != 0) { /* flood detection, wheeee! */ if(UNIXTIME >= floodTime) { floodLines = 0; floodTime = UNIXTIME + sWorld.flood_seconds; } if((++floodLines) > sWorld.flood_lines) { if(sWorld.flood_message) _player->BroadcastMessage("Your message has triggered serverside flood protection. You can speak again in %u seconds.", floodTime - UNIXTIME); return; } } switch(type) { case CHAT_MSG_EMOTE: case CHAT_MSG_SAY: case CHAT_MSG_YELL: case CHAT_MSG_WHISPER: case CHAT_MSG_CHANNEL: { if(m_muted && m_muted >= (uint32)UNIXTIME) { SystemMessage("Your voice is currently muted by a moderator."); return; } } break; } std::string msg, to = "", channel = "", tmp; msg.reserve(256); // Process packet switch(type) { case CHAT_MSG_SAY: case CHAT_MSG_EMOTE: case CHAT_MSG_PARTY: case CHAT_MSG_PARTY_LEADER: case CHAT_MSG_RAID: case CHAT_MSG_RAID_LEADER: case CHAT_MSG_RAID_WARNING: case CHAT_MSG_GUILD: case CHAT_MSG_OFFICER: case CHAT_MSG_YELL: recv_data >> msg; pMsg = msg.c_str(); //g_chatFilter->ParseEscapeCodes((char*)pMsg,true); pMisc = 0; break; case CHAT_MSG_WHISPER: recv_data >> to >> msg; pMsg = msg.c_str(); pMisc = to.c_str(); break; case CHAT_MSG_CHANNEL: recv_data >> channel; recv_data >> msg; pMsg = msg.c_str(); pMisc = channel.c_str(); break; case CHAT_MSG_AFK: case CHAT_MSG_DND: break; case CHAT_MSG_BATTLEGROUND: case CHAT_MSG_BATTLEGROUND_LEADER: recv_data >> msg; pMsg = msg.c_str(); break; default: LOG_ERROR("CHAT: unknown msg type %u, lang: %u", type, lang); } if(int(msg.find("|T")) > -1) { GetPlayer()->BroadcastMessage("Don't even THINK about doing that again"); return; } // HookInterface OnChat event if(pMsg && !sHookInterface.OnChat(_player, type, lang, pMsg, pMisc)) return; Channel* chn = NULL; // Main chat message processing switch(type) { case CHAT_MSG_EMOTE: { if(sWorld.interfaction_chat && lang > 0) lang = 0; if(g_chatFilter->Parse(msg)) { SystemMessage("Your chat message was blocked by a server-side filter."); return; } if(GetPlayer()->m_modlanguage >= 0) data = sChatHandler.FillMessageData(CHAT_MSG_EMOTE, GetPlayer()->m_modlanguage, msg.c_str(), _player->GetGUID(), _player->HasFlag(PLAYER_FLAGS, PLAYER_FLAG_GM) ? 4 : 0); else if(lang == 0 && sWorld.interfaction_chat) data = sChatHandler.FillMessageData(CHAT_MSG_EMOTE, CanUseCommand('0') ? LANG_UNIVERSAL : lang, msg.c_str(), _player->GetGUID(), _player->HasFlag(PLAYER_FLAGS, PLAYER_FLAG_GM) ? 4 : 0); else data = sChatHandler.FillMessageData(CHAT_MSG_EMOTE, CanUseCommand('c') ? LANG_UNIVERSAL : lang, msg.c_str(), _player->GetGUID(), _player->HasFlag(PLAYER_FLAGS, PLAYER_FLAG_GM) ? 4 : 0); GetPlayer()->SendMessageToSet(data, true, ! sWorld.interfaction_chat); //sLog.outString("[emote] %s: %s", _player->GetName(), msg.c_str()); delete data; } break; case CHAT_MSG_SAY: { if(sWorld.interfaction_chat && lang > 0) lang = 0; if(sChatHandler.ParseCommands(msg.c_str(), this) > 0) break; if(g_chatFilter->Parse(msg)) { SystemMessage("Your chat message was blocked by a server-side filter."); return; } if(GetPlayer()->m_modlanguage >= 0) { data = sChatHandler.FillMessageData(CHAT_MSG_SAY, GetPlayer()->m_modlanguage, msg.c_str(), _player->GetGUID(), _player->HasFlag(PLAYER_FLAGS, PLAYER_FLAG_GM) ? 4 : 0); GetPlayer()->SendMessageToSet(data, true); } else { if(lang > 0 && LanguageSkills[lang] && ! _player->_HasSkillLine(LanguageSkills[lang])) return; if(lang == 0 && ! CanUseCommand('c') && ! sWorld.interfaction_chat) return; data = sChatHandler.FillMessageData(CHAT_MSG_SAY, lang, msg.c_str(), _player->GetGUID(), _player->HasFlag(PLAYER_FLAGS, PLAYER_FLAG_GM) ? 4 : 0); GetPlayer()->SendMessageToSet(data, true); } delete data; } break; case CHAT_MSG_PARTY: case CHAT_MSG_PARTY_LEADER: case CHAT_MSG_RAID: case CHAT_MSG_RAID_LEADER: case CHAT_MSG_RAID_WARNING: { if(sChatHandler.ParseCommands(msg.c_str(), this) > 0) break; if(sWorld.interfaction_chat && lang > 0) lang = 0; if(g_chatFilter->Parse(msg) == true) { SystemMessage("Your chat message was blocked by a server-side filter."); return; } Group* pGroup = _player->GetGroup(); if(pGroup == NULL) break; if(GetPlayer()->m_modlanguage >= 0) data = sChatHandler.FillMessageData(type, GetPlayer()->m_modlanguage, msg.c_str(), _player->GetGUID(), _player->HasFlag(PLAYER_FLAGS, PLAYER_FLAG_GM) ? 4 : 0); else if(lang == 0 && sWorld.interfaction_chat) data = sChatHandler.FillMessageData(type, (CanUseCommand('0') && lang != -1) ? LANG_UNIVERSAL : lang, msg.c_str(), _player->GetGUID(), _player->HasFlag(PLAYER_FLAGS, PLAYER_FLAG_GM) ? 4 : 0); else data = sChatHandler.FillMessageData(type, (CanUseCommand('c') && lang != -1) ? LANG_UNIVERSAL : lang, msg.c_str(), _player->GetGUID(), _player->HasFlag(PLAYER_FLAGS, PLAYER_FLAG_GM) ? 4 : 0); if(type == CHAT_MSG_PARTY && pGroup->GetGroupType() == GROUP_TYPE_RAID) { // only send to that subgroup SubGroup* sgr = _player->GetGroup() ? _player->GetGroup()->GetSubGroup(_player->GetSubGroup()) : 0; if(sgr) { _player->GetGroup()->Lock(); for(GroupMembersSet::iterator itr = sgr->GetGroupMembersBegin(); itr != sgr->GetGroupMembersEnd(); ++itr) { if((*itr)->m_loggedInPlayer) (*itr)->m_loggedInPlayer->GetSession()->SendChatPacket(data, 1, lang, this); } _player->GetGroup()->Unlock(); } } else { SubGroup* sgr; for(uint32 i = 0; i < _player->GetGroup()->GetSubGroupCount(); ++i) { sgr = _player->GetGroup()->GetSubGroup(i); _player->GetGroup()->Lock(); for(GroupMembersSet::iterator itr = sgr->GetGroupMembersBegin(); itr != sgr->GetGroupMembersEnd(); ++itr) { if((*itr)->m_loggedInPlayer) (*itr)->m_loggedInPlayer->GetSession()->SendChatPacket(data, 1, lang, this); } _player->GetGroup()->Unlock(); } } //sLog.outString("[party] %s: %s", _player->GetName(), msg.c_str()); delete data; } break; case CHAT_MSG_GUILD: { if(sChatHandler.ParseCommands(msg.c_str(), this) > 0) { break; } if(g_chatFilter->Parse(msg) == true) { SystemMessage("Your chat message was blocked by a server-side filter."); return; } if(_player->m_playerInfo->guild) _player->m_playerInfo->guild->GuildChat(msg.c_str(), this, lang); } break; case CHAT_MSG_OFFICER: { if(sChatHandler.ParseCommands(msg.c_str(), this) > 0) break; if(g_chatFilter->Parse(msg) == true) { SystemMessage("Your chat message was blocked by a server-side filter."); return; } if(_player->m_playerInfo->guild) _player->m_playerInfo->guild->OfficerChat(msg.c_str(), this, lang); } break; case CHAT_MSG_YELL: { if(sWorld.interfaction_chat && lang > 0) lang = 0; if(sChatHandler.ParseCommands(msg.c_str(), this) > 0) break; if(g_chatFilter->Parse(msg) == true) { SystemMessage("Your chat message was blocked by a server-side filter."); return; } if(lang > 0 && LanguageSkills[lang] && _player->_HasSkillLine(LanguageSkills[lang]) == false) return; if(lang == 0 && sWorld.interfaction_chat) data = sChatHandler.FillMessageData(CHAT_MSG_YELL, (CanUseCommand('0') && lang != -1) ? LANG_UNIVERSAL : lang, msg.c_str(), _player->GetGUID(), _player->HasFlag(PLAYER_FLAGS, PLAYER_FLAG_GM) ? 4 : 0); else if(lang == 0 && !CanUseCommand('c')) { if(data != NULL) delete data; return; } else if(GetPlayer()->m_modlanguage >= 0) data = sChatHandler.FillMessageData(CHAT_MSG_YELL, GetPlayer()->m_modlanguage, msg.c_str(), _player->GetGUID(), _player->HasFlag(PLAYER_FLAGS, PLAYER_FLAG_GM) ? 4 : 0); else data = sChatHandler.FillMessageData(CHAT_MSG_YELL, (CanUseCommand('c') && lang != -1) ? LANG_UNIVERSAL : lang, msg.c_str(), _player->GetGUID(), _player->HasFlag(PLAYER_FLAGS, PLAYER_FLAG_GM) ? 4 : 0); _player->GetMapMgr()->SendChatMessageToCellPlayers(_player, data, 2, 1, lang, this); delete data; } break; case CHAT_MSG_WHISPER: { if(lang != -1) lang = LANG_UNIVERSAL; //All whispers are universal if(g_chatFilter->Parse(msg) == true) { SystemMessage("Your chat message was blocked by a server-side filter."); return; } PlayerCache* playercache = objmgr.GetPlayerCache(to.c_str(), false); if(playercache == NULL) { data = new WorldPacket(SMSG_CHAT_PLAYER_NOT_FOUND, to.length() + 1); *data << to; SendPacket(data); delete data; break; } if(_player->GetTeamInitial() != playercache->GetUInt32Value(CACHE_PLAYER_INITIALTEAM) && !sWorld.interfaction_chat && !playercache->HasFlag(CACHE_PLAYER_FLAGS, PLAYER_FLAG_GM) && !_player->HasFlag(PLAYER_FLAGS, PLAYER_FLAG_GM)) { WorldPacket response(SMSG_CHAT_PLAYER_NOT_FOUND, to.length() + 1); response << to; SendPacket(&response); playercache->DecRef(); break; } // Check that the player isn't a gm with his status on // TODO: Game Master's on retail are able to have block whispers after they close the ticket with the current packet. // When a Game Master is visible to your player it says "This player is unavailable for whisper" I need to figure out how this done. if(!HasPermissions() && playercache->HasFlag(CACHE_PLAYER_FLAGS, PLAYER_FLAG_GM) && playercache->CountValue64(CACHE_GM_TARGETS, _player->GetGUID()) == 0) { // Build automated reply string Reply = "SYSTEM: This Game Master does not currently have an open ticket from you and did not receive your whisper. Please submit a new GM Ticket request if you need to speak to a GM. This is an automatic message."; data = sChatHandler.FillMessageData(CHAT_MSG_WHISPER_INFORM, LANG_UNIVERSAL, Reply.c_str(), playercache->GetGUID(), 4); SendPacket(data); delete data; playercache->DecRef(); break; } if(playercache->CountValue64(CACHE_SOCIAL_IGNORELIST, _player->GetLowGUID()) > 0) { data = sChatHandler.FillMessageData(CHAT_MSG_IGNORED, LANG_UNIVERSAL, msg.c_str(), playercache->GetGUID(), _player->HasFlag(PLAYER_FLAGS, PLAYER_FLAG_GM) ? 4 : 0); SendPacket(data); delete data; playercache->DecRef(); break; } else { data = sChatHandler.FillMessageData(CHAT_MSG_WHISPER, lang, msg.c_str(), _player->GetGUID(), _player->HasFlag(PLAYER_FLAGS, PLAYER_FLAG_GM) ? 4 : 0); playercache->SendPacket(data); } //Sent the to Users id as the channel, this should be fine as it's not used for whisper if(lang != -1) //DO NOT SEND if its an addon message! { data = sChatHandler.FillMessageData(CHAT_MSG_WHISPER_INFORM, LANG_UNIVERSAL, msg.c_str(), playercache->GetGUID(), playercache->HasFlag(CACHE_PLAYER_FLAGS, PLAYER_FLAG_GM) ? 4 : 0); SendPacket(data); delete data; } if(playercache->HasFlag(CACHE_PLAYER_FLAGS, PLAYER_FLAG_AFK)) { // Has AFK flag, autorespond. std::string reason; playercache->GetStringValue(CACHE_AFK_DND_REASON, reason); data = sChatHandler.FillMessageData(CHAT_MSG_AFK, LANG_UNIVERSAL, reason.c_str(), playercache->GetGUID(), _player->HasFlag(PLAYER_FLAGS, PLAYER_FLAG_GM) ? 4 : 0); SendPacket(data); delete data; } else if(playercache->HasFlag(CACHE_PLAYER_FLAGS, PLAYER_FLAG_DND)) { // Has DND flag, autorespond. std::string reason; playercache->GetStringValue(CACHE_AFK_DND_REASON, reason); data = sChatHandler.FillMessageData(CHAT_MSG_DND, LANG_UNIVERSAL, reason.c_str(), playercache->GetGUID(), playercache->HasFlag(CACHE_PLAYER_FLAGS, PLAYER_FLAG_GM) ? 4 : 0); SendPacket(data); delete data; } playercache->DecRef(); } break; case CHAT_MSG_CHANNEL: { if(g_chatFilter->Parse(msg) == true) { SystemMessage("Your chat message was blocked by a server-side filter."); return; } if(sChatHandler.ParseCommands(msg.c_str(), this) > 0) break; chn = channelmgr.GetChannel(channel.c_str(), GetPlayer()); if(chn) { //g_chatFilter->ParseEscapeCodes((char*)pMsg, (chn->m_flags & CHANNEL_PACKET_ALLOWLINKS)>0 ); chn->Say(GetPlayer(), msg.c_str(), NULL, false); } } break; case CHAT_MSG_AFK: { std::string reason = ""; recv_data >> reason; GetPlayer()->SetAFKReason(reason); if(g_chatFilter->Parse(msg) == true) { SystemMessage("Your chat message was blocked by a server-side filter."); return; } /* WorldPacket *data, WorldSession* session, uint32 type, uint32 language, const char *channelName, const char *message*/ if(GetPlayer()->HasFlag(PLAYER_FLAGS, PLAYER_FLAG_AFK)) { GetPlayer()->RemoveFlag(PLAYER_FLAGS, PLAYER_FLAG_AFK); if(sWorld.GetKickAFKPlayerTime()) sEventMgr.RemoveEvents(GetPlayer(), EVENT_PLAYER_SOFT_DISCONNECT); } else { GetPlayer()->SetFlag(PLAYER_FLAGS, PLAYER_FLAG_AFK); if(GetPlayer()->m_bg) GetPlayer()->m_bg->RemovePlayer(GetPlayer(), false); if(sWorld.GetKickAFKPlayerTime()) sEventMgr.AddEvent(GetPlayer(), &Player::SoftDisconnect, EVENT_PLAYER_SOFT_DISCONNECT, sWorld.GetKickAFKPlayerTime(), 1, 0); } } break; case CHAT_MSG_DND: { std::string reason; recv_data >> reason; GetPlayer()->SetAFKReason(reason); if(g_chatFilter->Parse(msg) == true) { SystemMessage("Your chat message was blocked by a server-side filter."); return; } if(GetPlayer()->HasFlag(PLAYER_FLAGS, PLAYER_FLAG_DND)) GetPlayer()->RemoveFlag(PLAYER_FLAGS, PLAYER_FLAG_DND); else { GetPlayer()->SetFlag(PLAYER_FLAGS, PLAYER_FLAG_DND); } } break; case CHAT_MSG_BATTLEGROUND: case CHAT_MSG_BATTLEGROUND_LEADER: { if(sChatHandler.ParseCommands(msg.c_str(), this) > 0) break; if(g_chatFilter->Parse(msg) == true) { SystemMessage("Your chat message was blocked by a server-side filter."); return; } if(_player->m_bg != NULL) { data = sChatHandler.FillMessageData(type, lang, msg.c_str(), _player->GetGUID()); _player->m_bg->DistributePacketToTeam(data, _player->GetTeam()); delete data; } } break; } }
void WorldSession::HandleRaidTargetUpdateOpcode(WorldPacket& recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_RAID_TARGET_UPDATE"); Group* group = GetPlayer()->GetGroup(); if (!group) return; uint8 x, unk; recvData >> unk; recvData >> x; /** error handling **/ /********************/ // everything's fine, do it if (x == 0xFF) // target icon request group->SendTargetIconList(this); else // target icon update { if (!group->IsLeader(GetPlayer()->GetGUID()) && !group->IsAssistant(GetPlayer()->GetGUID()) && !(group->GetGroupType() & GROUPTYPE_EVERYONE_IS_ASSISTANT)) return; ObjectGuid guid; uint8 bitOrder[8] = { 2, 1, 6, 4, 5, 0, 7, 3 }; recvData.ReadBitInOrder(guid, bitOrder); recvData.FlushBits(); uint8 byteOrder[8] = { 5, 4, 6, 0, 1, 2, 3, 7 }; recvData.ReadBytesSeq(guid, byteOrder); group->SetTargetIcon(x, _player->GetGUID(), guid); } }
void WorldSession::HandleRaidLeaderReadyCheck(WorldPacket& recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_RAID_LEADER_READY_CHECK"); Group* group = GetPlayer()->GetGroup(); if (!group) return; if (!group->IsLeader(GetPlayer()->GetGUID()) && !group->IsAssistant(GetPlayer()->GetGUID()) && !(group->GetGroupType() & GROUPTYPE_EVERYONE_IS_ASSISTANT)) return; uint32 readyCheckDuration = 35000; ObjectGuid groupGUID = group->GetGUID(); ObjectGuid leaderGUID = GetPlayer()->GetGUID(); group->SetReadyCheckCount(1); WorldPacket data(SMSG_RAID_READY_CHECK, 1 + 8 + 1 + 8 + 1 + 4); data.WriteBit(groupGUID[4]); data.WriteBit(groupGUID[2]); data.WriteBit(leaderGUID[4]); data.WriteBit(groupGUID[3]); data.WriteBit(groupGUID[7]); data.WriteBit(groupGUID[1]); data.WriteBit(groupGUID[0]); data.WriteBit(leaderGUID[6]); data.WriteBit(leaderGUID[5]); data.WriteBit(groupGUID[6]); data.WriteBit(groupGUID[5]); data.WriteBit(leaderGUID[0]); data.WriteBit(leaderGUID[1]); data.WriteBit(leaderGUID[2]); data.WriteBit(leaderGUID[7]); data.WriteBit(leaderGUID[3]); data << uint32(readyCheckDuration); data.WriteByteSeq(groupGUID[2]); data.WriteByteSeq(groupGUID[7]); data.WriteByteSeq(groupGUID[3]); data.WriteByteSeq(leaderGUID[4]); data.WriteByteSeq(groupGUID[1]); data.WriteByteSeq(groupGUID[0]); data.WriteByteSeq(leaderGUID[1]); data.WriteByteSeq(leaderGUID[2]); data.WriteByteSeq(leaderGUID[6]); data.WriteByteSeq(leaderGUID[5]); data.WriteByteSeq(groupGUID[6]); data.WriteByteSeq(leaderGUID[0]); data << uint8(0); // unknown data.WriteByteSeq(leaderGUID[7]); data.WriteByteSeq(groupGUID[4]); data.WriteByteSeq(leaderGUID[3]); data.WriteByteSeq(groupGUID[5]); group->BroadcastPacket(&data, false, -1); group->OfflineReadyCheck(); }
void WorldSession::HandleGroupSetRolesOpcode(WorldPacket& recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_GROUP_SET_ROLES"); ObjectGuid targetGuid; // Target GUID uint32 newRole = 0; uint8 unk = 0; recvData >> unk; recvData >> newRole; uint8 bitOrder[8] = { 5, 3, 1, 0, 2, 6, 7, 4 }; recvData.ReadBitInOrder(targetGuid, bitOrder); recvData.FlushBits(); uint8 byteOrder[8] = { 4, 6, 1, 3, 0, 7, 5, 2 }; recvData.ReadBytesSeq(targetGuid, byteOrder); Player* tPlayer = ObjectAccessor::FindPlayer(targetGuid); Group* group = GetPlayer()->GetGroup(); if (!tPlayer) return; if (tPlayer && group) { // If the target is in another group. if (group != tPlayer->GetGroup()) return; // If the target is in the same group but the assigner is not the target itself, neither the leader or assistant (Can only change own roles). if (!group->IsLeader(GetPlayer()->GetGUID()) && !group->IsAssistant(GetPlayer()->GetGUID()) && !(group->GetGroupType() & GROUPTYPE_EVERYONE_IS_ASSISTANT)) if (GetPlayer() != tPlayer) return; } ObjectGuid assignerGuid = GetPlayer()->GetGUID(); // Assigner GUID WorldPacket data(SMSG_ROLE_CHANGED_INFORM, 1 + 8 + 1 + 8 + 4 + 1 + 4); data.WriteBit(targetGuid[3]); data.WriteBit(assignerGuid[3]); data.WriteBit(assignerGuid[0]); data.WriteBit(targetGuid[5]); data.WriteBit(targetGuid[4]); data.WriteBit(assignerGuid[1]); data.WriteBit(assignerGuid[7]); data.WriteBit(assignerGuid[4]); data.WriteBit(targetGuid[0]); data.WriteBit(assignerGuid[2]); data.WriteBit(targetGuid[2]); data.WriteBit(assignerGuid[5]); data.WriteBit(targetGuid[6]); data.WriteBit(targetGuid[1]); data.WriteBit(assignerGuid[6]); data.WriteBit(targetGuid[7]); data.FlushBits(); data.WriteByteSeq(assignerGuid[5]); data.WriteByteSeq(targetGuid[7]); data.WriteByteSeq(assignerGuid[4]); data.WriteByteSeq(targetGuid[3]); data.WriteByteSeq(assignerGuid[1]); data.WriteByteSeq(assignerGuid[0]); data << uint32(newRole); // New Role data.WriteByteSeq(assignerGuid[6]); data << uint8(unk); // Unknown - The uint8 in the CMSG above. data.WriteByteSeq(targetGuid[2]); data.WriteByteSeq(targetGuid[5]); data.WriteByteSeq(targetGuid[1]); data.WriteByteSeq(assignerGuid[3]); data << uint32(group ? group->getGroupMemberRole(targetGuid) : 0); // Old Role data.WriteByteSeq(targetGuid[4]); data.WriteByteSeq(assignerGuid[2]); data.WriteByteSeq(targetGuid[0]); data.WriteByteSeq(assignerGuid[7]); data.WriteByteSeq(targetGuid[6]); if (group) { group->setGroupMemberRole(targetGuid, newRole); group->SendUpdate(); group->BroadcastPacket(&data, false); } else SendPacket(&data); }
void WorldSession::HandleClearRaidMarkerOpcode(WorldPacket& recvData) { int8 markerId; recvData >> markerId; Player* plr = GetPlayer(); if (!plr) return; Group* group = plr->GetGroup(); if (!group) return; if (!group->isRaidGroup() || group->isRaidGroup() && (group->IsAssistant(plr->GetGUID()) || group->IsLeader(plr->GetGUID())) || group->GetGroupType() & GROUPTYPE_EVERYONE_IS_ASSISTANT) { if (markerId < MAX_RAID_MARKERS) group->RemoveRaidMarker(markerId); else group->RemoveAllRaidMarkers(); } }
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); }
void WorldSession::HandleRaidLeaderReadyCheck(WorldPacket& recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_RAID_LEADER_READY_CHECK"); recvData.read_skip<uint8>(); // unk, 0x00 Group* group = GetPlayer()->GetGroup(); if (!group) return; if (!group->IsLeader(GetPlayer()->GetGUID()) && !group->IsAssistant(GetPlayer()->GetGUID()) && !(group->GetGroupType() & GROUPTYPE_EVERYONE_IS_ASSISTANT)) return; ObjectGuid groupGuid = group->GetGUID(); ObjectGuid playerGuid = GetPlayer()->GetGUID(); // For the initiator being ready. group->SetReadyCheckCount(1); // Everything's fine, do it. WorldPacket data(SMSG_RAID_READY_CHECK_STARTED, 1 + 8 + 1 + 8 + 1 + 4); data.WriteBit(playerGuid[4]); data.WriteBit(groupGuid[1]); data.WriteBit(groupGuid[4]); data.WriteBit(playerGuid[6]); data.WriteBit(groupGuid[7]); data.WriteBit(groupGuid[6]); data.WriteBit(playerGuid[2]); data.WriteBit(playerGuid[0]); data.WriteBit(playerGuid[7]); data.WriteBit(groupGuid[0]); data.WriteBit(groupGuid[3]); data.WriteBit(groupGuid[5]); data.WriteBit(playerGuid[5]); data.WriteBit(playerGuid[3]); data.WriteBit(playerGuid[1]); data.WriteBit(groupGuid[2]); data.FlushBits(); data.WriteByteSeq(groupGuid[6]); data.WriteByteSeq(groupGuid[0]); data.WriteByteSeq(playerGuid[4]); data.WriteByteSeq(playerGuid[7]); data.WriteByteSeq(groupGuid[5]); data.WriteByteSeq(groupGuid[7]); data.WriteByteSeq(playerGuid[6]); data.WriteByteSeq(playerGuid[3]); data << uint8(0); // Unknown data.WriteByteSeq(groupGuid[1]); data.WriteByteSeq(playerGuid[2]); data.WriteByteSeq(groupGuid[3]); data.WriteByteSeq(playerGuid[5]); data.WriteByteSeq(groupGuid[4]); data.WriteByteSeq(groupGuid[2]); data << uint32(35000); // Ready check duration (35 sec) data.WriteByteSeq(playerGuid[1]); data.WriteByteSeq(playerGuid[0]); group->BroadcastPacket(&data, false, -1); group->OfflineReadyCheck(); }
void WorldSession::HandleMessagechatOpcode( WorldPacket & recv_data ) { CHECK_PACKET_SIZE(recv_data, 9); WorldPacket *data; if(!_player->IsInWorld()) return; uint32 type; int32 lang; const char * pMisc = 0; const char * pMsg = 0; recv_data >> type; recv_data >> lang; if( lang >= NUM_LANGUAGES ) return; if(GetPlayer()->IsBanned()) { GetPlayer()->BroadcastMessage("You cannot do that when banned."); return; } if(lang != -1 && !GetPermissionCount() && sWorld.flood_lines) { /* flood detection, wheeee! */ if(UNIXTIME >= floodTime) { floodLines = 0; floodTime = UNIXTIME + sWorld.flood_seconds; } if((++floodLines) > sWorld.flood_lines) { if(sWorld.flood_message) _player->BroadcastMessage("Your message has triggered serverside flood protection. You can speak again in %u seconds.", floodTime - UNIXTIME); return; } } std::stringstream irctext; irctext.rdbuf()->str(""); std::string msg; msg.reserve(256); //arghhh STFU. I'm not giving you gold or items NOOB switch(type) { case CHAT_MSG_EMOTE: case CHAT_MSG_SAY: case CHAT_MSG_YELL: case CHAT_MSG_WHISPER: case CHAT_MSG_CHANNEL: { if( m_muted && m_muted >= (uint32)UNIXTIME ) { SystemMessage("Your voice is currently muted by a moderator."); return; } }break; } switch(type) { case CHAT_MSG_EMOTE: { recv_data >> msg; if(GetPlayer()->m_modlanguage >=0) data = sChatHandler.FillMessageData( CHAT_MSG_EMOTE, GetPlayer()->m_modlanguage, msg.c_str(), _player->GetGUID(), _player->bGMTagOn ? 4 : 0 ); else data = sChatHandler.FillMessageData( CHAT_MSG_EMOTE, CanUseCommand('c') ? LANG_UNIVERSAL : lang, msg.c_str(), _player->GetGUID(), _player->bGMTagOn ? 4 : 0 ); GetPlayer()->SendMessageToSet( data, true ,true ); //sLog.outString("[emote] %s: %s", _player->GetName(), msg.c_str()); delete data; pMsg=msg.c_str(); pMisc=0; }break; case CHAT_MSG_SAY: { recv_data >> msg; if (sChatHandler.ParseCommands(msg.c_str(), this) > 0) break; if(g_chatFilter->Parse(msg) == true) { SystemMessage("Your chat message was blocked by a server-side filter."); return; } if(GetPlayer()->m_modlanguage >=0) { data = sChatHandler.FillMessageData( CHAT_MSG_SAY, GetPlayer()->m_modlanguage, msg.c_str(), _player->GetGUID(), _player->bGMTagOn ? 4 : 0 ); GetPlayer()->SendMessageToSet( data, true ); } else { if(lang > 0 && LanguageSkills[lang] && _player->_HasSkillLine(LanguageSkills[lang]) == false) return; if(lang==0 && !CanUseCommand('c')) return; data = sChatHandler.FillMessageData( CHAT_MSG_SAY, lang, msg.c_str(), _player->GetGUID(), _player->bGMTagOn ? 4 : 0 ); SendChatPacket(data, 1, lang, this); for(set<Player*>::iterator itr = _player->m_inRangePlayers.begin(); itr != _player->m_inRangePlayers.end(); ++itr) { (*itr)->GetSession()->SendChatPacket(data, 1, lang, this); } } //sLog.outString("[say] %s: %s", _player->GetName(), msg.c_str()); delete data; pMsg=msg.c_str(); pMisc=0; } break; case CHAT_MSG_PARTY: case CHAT_MSG_RAID: case CHAT_MSG_RAID_LEADER: case CHAT_MSG_RAID_WARNING: { recv_data >> msg; if (sChatHandler.ParseCommands(msg.c_str(), this) > 0) break; if(g_chatFilter->Parse(msg) == true) { SystemMessage("Your chat message was blocked by a server-side filter."); return; } Group *pGroup = _player->GetGroup(); if(pGroup == NULL) break; if(GetPlayer()->m_modlanguage >=0) data=sChatHandler.FillMessageData( type, GetPlayer()->m_modlanguage, msg.c_str(), _player->GetGUID(), _player->bGMTagOn ? 4 : 0 ); else data=sChatHandler.FillMessageData( type, (CanUseCommand('c') && lang != -1) ? LANG_UNIVERSAL : lang, msg.c_str(), _player->GetGUID(), _player->bGMTagOn ? 4 : 0); if(type == CHAT_MSG_PARTY && pGroup->GetGroupType() == GROUP_TYPE_RAID) { // only send to that subgroup SubGroup * sgr = _player->GetGroup() ? _player->GetGroup()->GetSubGroup(_player->GetSubGroup()) : 0; if(sgr) { _player->GetGroup()->Lock(); for(GroupMembersSet::iterator itr = sgr->GetGroupMembersBegin(); itr != sgr->GetGroupMembersEnd(); ++itr) { if((*itr)->m_loggedInPlayer) (*itr)->m_loggedInPlayer->GetSession()->SendChatPacket(data, 1, lang, this); } _player->GetGroup()->Unlock(); } } else { SubGroup * sgr; for(uint32 i = 0; i < _player->GetGroup()->GetSubGroupCount(); ++i) { sgr = _player->GetGroup()->GetSubGroup(i); _player->GetGroup()->Lock(); for(GroupMembersSet::iterator itr = sgr->GetGroupMembersBegin(); itr != sgr->GetGroupMembersEnd(); ++itr) { if((*itr)->m_loggedInPlayer) (*itr)->m_loggedInPlayer->GetSession()->SendChatPacket(data, 1, lang, this); } _player->GetGroup()->Unlock(); } } //sLog.outString("[party] %s: %s", _player->GetName(), msg.c_str()); delete data; pMsg=msg.c_str(); pMisc=0; } break; case CHAT_MSG_GUILD: { recv_data >> msg; if (sChatHandler.ParseCommands(msg.c_str(), this) > 0) { break; } if(g_chatFilter->Parse(msg) == true) { SystemMessage("Your chat message was blocked by a server-side filter."); return; } if(_player->m_playerInfo->guild) _player->m_playerInfo->guild->GuildChat(msg.c_str(), this, lang); pMsg=msg.c_str(); pMisc=0; } break; case CHAT_MSG_OFFICER: { recv_data >> msg; if (sChatHandler.ParseCommands(msg.c_str(), this) > 0) break; if(g_chatFilter->Parse(msg) == true) { SystemMessage("Your chat message was blocked by a server-side filter."); return; } if(_player->m_playerInfo->guild) _player->m_playerInfo->guild->OfficerChat(msg.c_str(), this, lang); pMsg=msg.c_str(); pMisc=0; } break; case CHAT_MSG_YELL: { recv_data >> msg; if (sChatHandler.ParseCommands(msg.c_str(), this) > 0) break; if(g_chatFilter->Parse(msg) == true) { SystemMessage("Your chat message was blocked by a server-side filter."); return; } if(lang > 0 && LanguageSkills[lang] && _player->_HasSkillLine(LanguageSkills[lang]) == false) return; if(lang==0 && !CanUseCommand('c')) return; if(GetPlayer()->m_modlanguage >=0) data = sChatHandler.FillMessageData( CHAT_MSG_YELL, GetPlayer()->m_modlanguage, msg.c_str(), _player->GetGUID(), _player->bGMTagOn ? 4 : 0 ); else data = sChatHandler.FillMessageData( CHAT_MSG_YELL, (CanUseCommand('c') && lang != -1) ? LANG_UNIVERSAL : lang, msg.c_str(), _player->GetGUID(), _player->bGMTagOn ? 4 : 0 ); //SendPacket(data); //sWorld.SendZoneMessage(data, GetPlayer()->GetZoneId(), this); _player->GetMapMgr()->SendChatMessageToCellPlayers(_player, data, 2, 1, lang, this); delete data; //sLog.outString("[yell] %s: %s", _player->GetName(), msg.c_str()); pMsg=msg.c_str(); pMisc=0; } break; case CHAT_MSG_WHISPER: { std::string to = "",tmp; recv_data >> to >> msg; if(g_chatFilter->Parse(msg) == true) { SystemMessage("Your chat message was blocked by a server-side filter."); return; } Player *player = objmgr.GetPlayer(to.c_str(), false); if(!player) { data = new WorldPacket(SMSG_CHAT_PLAYER_NOT_FOUND, to.length() + 1); *data << to; SendPacket(data); delete data; break; } // Check that the player isn't a gm with his status on if(!_player->GetSession()->GetPermissionCount() && player->bGMTagOn && player->gmTargets.count(_player) == 0) { // Send CHAT_MSG_WHISPER_INFORM packet WorldPacket *data2; data2 = sChatHandler.FillMessageData(CHAT_MSG_WHISPER_INFORM, LANG_UNIVERSAL,msg.c_str(), player->GetGUID(), 0); SendPacket(data2); delete data2; // Build automated reply string Reply = "This Game Master does not currently have an open ticket from you and did not receive your whisper. Please submit a new GM Ticket request if you need to speak to a GM. This is an automatic message."; data = sChatHandler.FillMessageData( CHAT_MSG_WHISPER, LANG_UNIVERSAL, Reply.c_str(), player->GetGUID(), 4); SendPacket(data); delete data; break; } if(lang > 0 && LanguageSkills[lang] && _player->_HasSkillLine(LanguageSkills[lang]) == false) return; if(lang==0 && !CanUseCommand('c')) return; if( player->Social_IsIgnoring( _player->GetLowGUID() ) ) { data = sChatHandler.FillMessageData( CHAT_MSG_IGNORED, LANG_UNIVERSAL, msg.c_str(), _player->GetGUID(), _player->bGMTagOn ? 4 : 0 ); SendPacket(data); delete data; } else { if(GetPlayer()->m_modlanguage >=0) data = sChatHandler.FillMessageData( CHAT_MSG_WHISPER, GetPlayer()->m_modlanguage, msg.c_str(), _player->GetGUID(), _player->bGMTagOn ? 4 : 0 ); else data = sChatHandler.FillMessageData( CHAT_MSG_WHISPER, ((CanUseCommand('c') || player->GetSession()->CanUseCommand('c')) && lang != -1) ? LANG_UNIVERSAL : lang, msg.c_str(), _player->GetGUID(), _player->bGMTagOn ? 4 : 0 ); player->GetSession()->SendPacket(data); delete data; } //Sent the to Users id as the channel, this should be fine as it's not used for wisper data = sChatHandler.FillMessageData(CHAT_MSG_WHISPER_INFORM, LANG_UNIVERSAL,msg.c_str(), player->GetGUID(), 0 ); SendPacket(data); delete data; if(player->HasFlag(PLAYER_FLAGS, 0x02)) { // Has AFK flag, autorespond. data = sChatHandler.FillMessageData(CHAT_MSG_AFK, LANG_UNIVERSAL, player->m_afk_reason.c_str(),player->GetGUID(), _player->bGMTagOn ? 4 : 0); SendPacket(data); delete data; } else if(player->HasFlag(PLAYER_FLAGS, 0x04)) { // Has DND flag, autorespond. data = sChatHandler.FillMessageData(CHAT_MSG_DND, LANG_UNIVERSAL, player->m_afk_reason.c_str(),player->GetGUID(), _player->bGMTagOn ? 4 : 0); SendPacket(data); delete data; } //sLog.outString("[whisper] %s to %s: %s", _player->GetName(), to.c_str(), msg.c_str()); pMsg=msg.c_str(); pMisc=to.c_str(); } break; case CHAT_MSG_CHANNEL: { std::string channel = ""; recv_data >> channel; recv_data >> msg; if(g_chatFilter->Parse(msg) == true) { SystemMessage("Your chat message was blocked by a server-side filter."); return; } if (sChatHandler.ParseCommands(msg.c_str(), this) > 0) break; Channel *chn = channelmgr.GetChannel(channel.c_str(),GetPlayer()); if(chn) chn->Say(GetPlayer(),msg.c_str(), NULL, false); //sLog.outString("[%s] %s: %s", channel.c_str(), _player->GetName(), msg.c_str()); pMsg=msg.c_str(); pMisc=channel.c_str(); } break; case CHAT_MSG_AFK: { std::string reason; recv_data >> reason; GetPlayer()->SetAFKReason(reason); if(g_chatFilter->Parse(msg) == true) { SystemMessage("Your chat message was blocked by a server-side filter."); return; } /* WorldPacket *data, WorldSession* session, uint32 type, uint32 language, const char *channelName, const char *message*/ if(GetPlayer()->HasFlag(PLAYER_FLAGS, 0x02)) { GetPlayer()->RemoveFlag(PLAYER_FLAGS, 0x02); if(sWorld.GetKickAFKPlayerTime()) sEventMgr.RemoveEvents(GetPlayer(),EVENT_PLAYER_SOFT_DISCONNECT); } else { GetPlayer()->SetFlag(PLAYER_FLAGS, 0x02); if(sWorld.GetKickAFKPlayerTime()) sEventMgr.AddEvent(GetPlayer(),&Player::SoftDisconnect,EVENT_PLAYER_SOFT_DISCONNECT,sWorld.GetKickAFKPlayerTime(),1,0); } } break; case CHAT_MSG_DND: { std::string reason; recv_data >> reason; GetPlayer()->SetAFKReason(reason); if(g_chatFilter->Parse(msg) == true) { SystemMessage("Your chat message was blocked by a server-side filter."); return; } if(GetPlayer()->HasFlag(PLAYER_FLAGS, 0x04)) GetPlayer()->RemoveFlag(PLAYER_FLAGS, 0x04); else { GetPlayer()->SetFlag(PLAYER_FLAGS, 0x04); } } break; default: sLog.outError("CHAT: unknown msg type %u, lang: %u", type, lang); } if(pMsg) sHookInterface.OnChat(_player, type, lang, pMsg, pMisc); }
////////////////////////////////////////////////////////////// /// This function handles CMSG_GROUP_INVITE ////////////////////////////////////////////////////////////// void WorldSession::HandleGroupInviteOpcode( WorldPacket & recv_data ) { if(!_player->IsInWorld()) { return; } CHECK_PACKET_SIZE(recv_data, 1); std::string membername; Player * player = NULL; Group *group = NULL; recv_data.read_skip( 10 ); //no idea, they were all 0 recv_data >> membername; //tried to make sure the other guy can't accept the invited /* if( _player->HasBeenInvited() ) { return; } */ player = objmgr.GetPlayer(membername.c_str(), false); if ( player == NULL) { SendPartyCommandResult(_player, 0, membername, ERR_PARTY_CANNOT_FIND); return; } if (player == _player) { return; } if ( _player->InGroup() && !_player->IsGroupLeader() ) { SendPartyCommandResult(_player, 0, "", ERR_PARTY_YOU_ARE_NOT_LEADER); return; } group = _player->GetGroup(); if( group != NULL ) { if(group->IsFull()) { SendPartyCommandResult(_player, 0, "", ERR_PARTY_IS_FULL); return; } } if ( player->InGroup() ) { SendPartyCommandResult(_player, player->GetGroup()->GetGroupType(), membername, ERR_PARTY_ALREADY_IN_GROUP); return; } if(player->GetTeam()!=_player->GetTeam() && _player->GetSession()->GetPermissionCount() == 0 && !sWorld.interfaction_group) { SendPartyCommandResult(_player, 0, membername, ERR_PARTY_WRONG_FACTION); return; } //tried to make sure the other guy can't accept the invited /* if ( player->HasBeenInvited() ) { SendPartyCommandResult(_player, 0, membername, ERR_PARTY_ALREADY_IN_GROUP); return; }*/ if( player->Social_IsIgnoring( _player->GetLowGUID() ) ) { SendPartyCommandResult(_player, 0, membername, ERR_PARTY_IS_IGNORING_YOU); return; } /* {SERVER} Packet: (0x1F7F) SMSG_GROUP_INVITE PacketSize = 16 TimeStamp = 30686468 01 55 64 72 65 61 00 AA 2A 00 00 00 00 00 00 00 14333 {SERVER} Packet: (0x4723) UNKNOWN PacketSize = 44 TimeStamp = 17757047 4E E0 1001110 11100000 6F 00 00 00 03 go3 00 00 00 00 00 00 00 00 4C go2 44 75 6E 65 6D 61 75 6C 00 Dunemaul 00 00 00 00 41 6E 61 72 6B 65 00 Anarke 00 1F 59 15 00 go7 AF go1 81 go6 EB go0 {SERVER} Packet: (0xFA67) SMSG_NAME_QUERY_RESPONSE PacketSize = 20 TimeStamp = 17676894 CF EA AE 4D 02 80 01 00 41 6E 61 72 6B 65 00 00 02 00 06 00 {SERVER} Packet: (0x4723) UNKNOWN PacketSize = 46 TimeStamp = 18686064 4E E0 6F 00 00 00 00 00 00 00 00 42 00 00 00 81 44 75 6E 65 6D 61 75 6C 00 00 00 00 00 44 72 61 69 73 69 75 73 00 00 69 E3 1F 00 B0 81 F7 11001111 {SERVER} Packet: (0xFA67) SMSG_NAME_QUERY_RESPONSE PacketSize = 22 TimeStamp = 18570343 CF F6 B1 80 01 80 01 00 44 72 61 69 73 69 75 73 00 00 0A 00 03 00 */ uint64 inviter_guid = _player->GetGUID(); uint8 *guid_bytes = (uint8*)&inviter_guid; uint16 guid_mask = 0; //!!not confirmed, but seems to work ! /* if( guid_bytes[0] ) guid_mask |= BIT_0; if( guid_bytes[1] ) guid_mask |= BIT_1; if( guid_bytes[2] ) guid_mask |= BIT_2; if( guid_bytes[3] ) guid_mask |= BIT_3;*/ guid_mask = 0xE04E; sStackWorldPacket( data,SMSG_GROUP_INVITE, 100); data << uint16(guid_mask);//guid mask data << uint32( 0 ); //? // if( guid_bytes[3] ) data << ObfuscateByte( guid_bytes[3] ); data << uint32( 0x00000000 ); data << uint32( 0x00000000 ); // if( guid_bytes[2] ) data << ObfuscateByte( guid_bytes[2] ); data << ""; //realm name data << uint32( 0x00000000 ); data << GetPlayer()->GetName(); data << uint32( 0 ); // if( guid_bytes[7] ) data << ObfuscateByte( guid_bytes[7] ); // if( guid_bytes[1] ) data << ObfuscateByte( guid_bytes[1] ); // if( guid_bytes[6] ) data << ObfuscateByte( guid_bytes[6] ); // if( guid_bytes[0] ) data << ObfuscateByte( guid_bytes[0] ); player->GetSession()->SendPacket(&data); uint32 gtype = 0; if(group) gtype = group->GetGroupType(); SendPartyCommandResult(_player, gtype, membername, ERR_PARTY_NO_ERROR); // 16/08/06 - change to guid to prevent very unlikely event of a crash in deny, etc player->SetInviter( _player->GetLowGUID() ); // 16/08/06 - change to guid to prevent very unlikely event of a crash in deny, etc _player->SetInviter( player->GetLowGUID() );//bugfix if player invtied 2 people-> he can be in 2 parties }
uint32 InstanceMgr::PreTeleport(uint32 mapid, Player * plr, uint32 instanceid) { // preteleport is where all the magic happens :P instance creation, etc. MapInfo * inf = WorldMapInfoStorage.LookupEntry(mapid); Group * pGroup; InstanceMap * instancemap; Instance * in; if (inf == NULL || mapid >= NUM_MAPS) return INSTANCE_ABORT_NOT_FOUND; // main continent check. if (inf->type == INSTANCE_NULL) { // this will be useful when clustering comes into play. // we can check if the destination world server is online or not and then cancel them before they load. return (m_singleMaps[mapid] != NULL) ? INSTANCE_OK : INSTANCE_ABORT_NOT_FOUND; } // shouldn't happen if (inf->type == INSTANCE_PVP) return INSTANCE_ABORT_NOT_FOUND; pGroup = plr->GetGroup(); // players without groups cannot enter raids and heroic instances if (pGroup == NULL && (inf->type == INSTANCE_RAID || (inf->type == INSTANCE_MULTIMODE && plr->iInstanceType >= MODE_HEROIC)) && !plr->TriggerpassCheat) return INSTANCE_ABORT_NOT_IN_RAID_GROUP; // players without raid groups cannot enter raid instances if (pGroup != NULL && pGroup->GetGroupType() != GROUP_TYPE_RAID && inf->type == INSTANCE_RAID && !plr->TriggerpassCheat) return INSTANCE_ABORT_NOT_IN_RAID_GROUP; // check that heroic mode is available if the player has requested it. if (plr->iInstanceType && inf->type != INSTANCE_MULTIMODE) return INSTANCE_ABORT_HEROIC_MODE_NOT_AVAILABLE; // if we are here, it means: // 1) we're a non-raid instance // 2) we're a raid instance, and the person is in a group. // so, first we have to check if they have an instance on this map already, if so, allow them to teleport to that. // otherwise, we can create them a new one. m_mapLock.Acquire(); instancemap = m_instances[mapid]; if (instancemap == NULL) { if (instanceid != 0) { m_mapLock.Release(); return INSTANCE_ABORT_NOT_FOUND; } // gotta create the hashmap. m_instances[mapid] = new InstanceMap; instancemap = m_instances[mapid]; } else { InstanceMap::iterator itr; if (instanceid != 0) { itr = instancemap->find(instanceid); if (itr != instancemap->end()) { in = itr->second; if (!CHECK_INSTANCE_GROUP(in, pGroup)) { // Another group is already playing in this instance of the dungeon... m_mapLock.Release(); sChatHandler.SystemMessageToPlr(plr, "Another group is already inside this instance of the dungeon."); return INSTANCE_ABORT_NOT_IN_RAID_GROUP; } // Try to add instance ID to player plr->SetPersistentInstanceId(in); // Set current group if (pGroup) in->m_creatorGroup = pGroup->GetID(); m_mapLock.Release(); return INSTANCE_OK; } else { m_mapLock.Release(); return INSTANCE_ABORT_NOT_FOUND; } } else { in = NULL; if (pGroup != NULL) { if ((inf->type == INSTANCE_MULTIMODE && pGroup->m_difficulty >= MODE_HEROIC) || inf->type == INSTANCE_RAID) { if (plr->GetPersistentInstanceId(mapid, pGroup->m_difficulty) == 0) { if (pGroup->m_instanceIds[mapid][pGroup->m_difficulty] != 0) { in = sInstanceMgr.GetInstanceByIds(mapid, pGroup->m_instanceIds[mapid][pGroup->m_difficulty]); } else if (sWorld.instance_TakeGroupLeaderID) { PlayerInfo *pLeaderInfo = pGroup->GetLeader(); if (pLeaderInfo) { pLeaderInfo->savedInstanceIdsLock.Acquire(); PlayerInstanceMap::iterator itrLeader = pLeaderInfo->savedInstanceIds[pGroup->m_difficulty].find(mapid); if (itrLeader != pLeaderInfo->savedInstanceIds[pGroup->m_difficulty].end()) { in = sInstanceMgr.GetInstanceByIds(mapid, (*itrLeader).second); } pLeaderInfo->savedInstanceIdsLock.Release(); } } } if (in == NULL && plr->GetPersistentInstanceId(mapid, pGroup->m_difficulty) != 0) { in = sInstanceMgr.GetInstanceByIds(mapid, plr->GetPersistentInstanceId(mapid, pGroup->m_difficulty)); } } else { if (pGroup->m_instanceIds[mapid][pGroup->m_difficulty] != 0) { in = sInstanceMgr.GetInstanceByIds(mapid, pGroup->m_instanceIds[mapid][pGroup->m_difficulty]); } } } if (in == NULL) { // search the instance and see if we have one here. for (itr = instancemap->begin(); itr != instancemap->end();) { in = itr->second; ++itr; if (in->m_difficulty == plr->iInstanceType && PlayerOwnsInstance(in, plr)) break; in = NULL; } } if (in != NULL) { m_mapLock.Release(); // check the player count and in combat status. if (in->m_mapMgr) { if (in->m_mapMgr->IsCombatInProgress()) return INSTANCE_ABORT_ENCOUNTER; if (in->m_mapMgr->GetPlayerCount() >= inf->playerlimit) return INSTANCE_ABORT_FULL; } if (!CHECK_INSTANCE_GROUP(in, pGroup)) { // Another group is already playing in this instance of the dungeon... sChatHandler.SystemMessageToPlr(plr, "Another group is already inside this instance of the dungeon."); return INSTANCE_ABORT_NOT_IN_RAID_GROUP; } // Try to add instance ID to player plr->SetPersistentInstanceId(in); // Set current group if (pGroup) in->m_creatorGroup = pGroup->GetID(); plr->SetInstanceID(in->m_instanceId); // found our instance, allow him in. return INSTANCE_OK; } } } // if we're here, it means we need to create a new instance. in = new Instance; in->m_creation = UNIXTIME; in->m_difficulty = pGroup ? pGroup->m_difficulty : plr->iInstanceType; in->m_instanceId = GenerateInstanceID(); in->m_mapId = mapid; in->m_mapInfo = inf; in->m_mapMgr = NULL; // always start off without a map manager, it is created in GetInstance() in->m_isBattleground = false; in->m_persistent = IS_PERSISTENT_INSTANCE(in) && objmgr.m_InstanceBossInfoMap[mapid] == NULL; in->m_creatorGuid = pGroup ? 0 : plr->GetLowGUID(); // creator guid is 0 if its owned by a group. in->m_creatorGroup = pGroup ? pGroup->GetID() : 0; if (sWorld.instance_SlidingExpiration) { if (inf->type == INSTANCE_MULTIMODE && in->m_difficulty >= MODE_HEROIC) in->m_expiration = UNIXTIME + TIME_DAY; else in->m_expiration = (inf->type == INSTANCE_NONRAID || (inf->type == INSTANCE_MULTIMODE && in->m_difficulty == MODE_NORMAL)) ? 0 : UNIXTIME + inf->cooldown; } else { if (inf->type == INSTANCE_MULTIMODE && in->m_difficulty >= MODE_HEROIC) { in->m_expiration = UNIXTIME - (UNIXTIME % TIME_DAY) + ((UNIXTIME % TIME_DAY) > (sWorld.instance_DailyHeroicInstanceResetHour * TIME_HOUR) ? 82800 : -3600) + ((sWorld.instance_DailyHeroicInstanceResetHour - sWorld.GMTTimeZone) * TIME_HOUR); } else if (IS_PERSISTENT_INSTANCE(in)) { if (m_nextInstanceReset[in->m_mapId] == 0) { m_nextInstanceReset[in->m_mapId] = UNIXTIME - (UNIXTIME % TIME_DAY) - ((sWorld.GMTTimeZone + 1) * TIME_HOUR) + (in->m_mapInfo->cooldown == 0 ? TIME_DAY : in->m_mapInfo->cooldown); CharacterDatabase.Execute("REPLACE INTO `server_settings` (`setting_id`, `setting_value`) VALUES ('next_instance_reset_%u', '%u')", in->m_mapId, m_nextInstanceReset[in->m_mapId]); } if (m_nextInstanceReset[in->m_mapId] + (TIME_MINUTE * 15) < UNIXTIME) { do { time_t tmp = m_nextInstanceReset[in->m_mapId]; if (tmp + (TIME_MINUTE * 15) < UNIXTIME) m_nextInstanceReset[in->m_mapId] = tmp + (in->m_mapInfo->cooldown == 0 ? TIME_DAY : in->m_mapInfo->cooldown); } while (m_nextInstanceReset[in->m_mapId] + (TIME_MINUTE * 15) < UNIXTIME); CharacterDatabase.Execute("REPLACE INTO `server_settings` (`setting_id`, `setting_value`) VALUES ('next_instance_reset_%u', '%u')", in->m_mapId, m_nextInstanceReset[in->m_mapId]); } in->m_expiration = m_nextInstanceReset[in->m_mapId]; } else { in->m_expiration = (inf->type == INSTANCE_NONRAID || (inf->type == INSTANCE_MULTIMODE && in->m_difficulty == MODE_NORMAL)) ? 0 : UNIXTIME + inf->cooldown; } } plr->SetInstanceID(in->m_instanceId); Log.Debug("InstanceMgr", "Creating instance for player %u and group %u on map %u. (%u)", in->m_creatorGuid, in->m_creatorGroup, in->m_mapId, in->m_instanceId); // save our new instance to the database. in->SaveToDB(); // apply it in the instance map instancemap->insert(InstanceMap::value_type(in->m_instanceId, in)); // Try to add instance ID to player plr->SetPersistentInstanceId(in); // instance created ok, i guess? return the ok for him to transport. m_mapLock.Release(); return INSTANCE_OK; }