示例#1
0
        void HandleBattlemasterJoinArena(BattlemasterJoinArena packet)
        {
            // ignore if we already in BG or BG queue
            if (GetPlayer().InBattleground())
            {
                return;
            }

            ArenaTypes arenatype = (ArenaTypes)ArenaTeam.GetTypeBySlot(packet.TeamSizeIndex);

            //check existence
            Battleground bg = Global.BattlegroundMgr.GetBattlegroundTemplate(BattlegroundTypeId.AA);

            if (!bg)
            {
                Log.outError(LogFilter.Network, "Battleground: template bg (all arenas) not found");
                return;
            }

            if (Global.DisableMgr.IsDisabledFor(DisableType.Battleground, (uint)BattlegroundTypeId.AA, null))
            {
                GetPlayer().SendSysMessage(CypherStrings.ArenaDisabled);
                return;
            }

            BattlegroundTypeId      bgTypeId      = bg.GetTypeID();
            BattlegroundQueueTypeId bgQueueTypeId = Global.BattlegroundMgr.BGQueueTypeId(bgTypeId, arenatype);
            PvpDifficultyRecord     bracketEntry  = Global.DB2Mgr.GetBattlegroundBracketByLevel(bg.GetMapId(), GetPlayer().getLevel());

            if (bracketEntry == null)
            {
                return;
            }

            Group grp = GetPlayer().GetGroup();

            // no group found, error
            if (!grp)
            {
                return;
            }
            if (grp.GetLeaderGUID() != GetPlayer().GetGUID())
            {
                return;
            }

            uint ateamId = GetPlayer().GetArenaTeamId(packet.TeamSizeIndex);
            // check real arenateam existence only here (if it was moved to group.CanJoin .. () then we would ahve to get it twice)
            ArenaTeam at = Global.ArenaTeamMgr.GetArenaTeamById(ateamId);

            if (at == null)
            {
                GetPlayer().GetSession().SendNotInArenaTeamPacket(arenatype);
                return;
            }

            // get the team rating for queuing
            uint arenaRating      = at.GetRating();
            uint matchmakerRating = at.GetAverageMMR(grp);

            // the arenateam id must match for everyone in the group

            if (arenaRating <= 0)
            {
                arenaRating = 1;
            }

            BattlegroundQueue bgQueue = Global.BattlegroundMgr.GetBattlegroundQueue(bgQueueTypeId);

            uint           avgTime = 0;
            GroupQueueInfo ginfo   = null;

            ObjectGuid errorGuid;
            var        err = grp.CanJoinBattlegroundQueue(bg, bgQueueTypeId, (uint)arenatype, (uint)arenatype, true, packet.TeamSizeIndex, out errorGuid);

            if (err == 0)
            {
                Log.outDebug(LogFilter.Battleground, "Battleground: arena team id {0}, leader {1} queued with matchmaker rating {2} for type {3}", GetPlayer().GetArenaTeamId(packet.TeamSizeIndex), GetPlayer().GetName(), matchmakerRating, arenatype);

                ginfo   = bgQueue.AddGroup(GetPlayer(), grp, bgTypeId, bracketEntry, arenatype, true, false, arenaRating, matchmakerRating, ateamId);
                avgTime = bgQueue.GetAverageQueueWaitTime(ginfo, bracketEntry.GetBracketId());
            }

            for (GroupReference refe = grp.GetFirstMember(); refe != null; refe = refe.next())
            {
                Player member = refe.GetSource();
                if (!member)
                {
                    continue;
                }

                if (err != 0)
                {
                    BattlefieldStatusFailed battlefieldStatus;
                    Global.BattlegroundMgr.BuildBattlegroundStatusFailed(out battlefieldStatus, bg, GetPlayer(), 0, arenatype, err, errorGuid);
                    member.SendPacket(battlefieldStatus);
                    continue;
                }

                // add to queue
                uint queueSlot = member.AddBattlegroundQueueId(bgQueueTypeId);

                BattlefieldStatusQueued battlefieldStatusQueued;
                Global.BattlegroundMgr.BuildBattlegroundStatusQueued(out battlefieldStatusQueued, bg, member, queueSlot, ginfo.JoinTime, avgTime, arenatype, true);
                member.SendPacket(battlefieldStatusQueued);

                Log.outDebug(LogFilter.Battleground, "Battleground: player joined queue for arena as group bg queue type {0} bg type {1}: GUID {2}, NAME {3}", bgQueueTypeId, bgTypeId, member.GetGUID().ToString(), member.GetName());
            }

            Global.BattlegroundMgr.ScheduleQueueUpdate(matchmakerRating, arenatype, bgQueueTypeId, bgTypeId, bracketEntry.GetBracketId());
        }
示例#2
0
        void HandleBattlemasterJoin(BattlemasterJoin battlemasterJoin)
        {
            bool  isPremade = false;
            Group grp       = null;

            BattlefieldStatusFailed battlefieldStatusFailed;

            uint bgTypeId_ = (uint)(battlemasterJoin.QueueID & 0xFFFF);

            if (!CliDB.BattlemasterListStorage.ContainsKey(bgTypeId_))
            {
                Log.outError(LogFilter.Network, "Battleground: invalid bgtype ({0}) received. possible cheater? player guid {1}", bgTypeId_, GetPlayer().GetGUID().ToString());
                return;
            }

            if (Global.DisableMgr.IsDisabledFor(DisableType.Battleground, bgTypeId_, null))
            {
                GetPlayer().SendSysMessage(CypherStrings.BgDisabled);
                return;
            }
            BattlegroundTypeId bgTypeId = (BattlegroundTypeId)bgTypeId_;

            // can do this, since it's Battleground, not arena
            BattlegroundQueueTypeId bgQueueTypeId       = Global.BattlegroundMgr.BGQueueTypeId(bgTypeId, 0);
            BattlegroundQueueTypeId bgQueueTypeIdRandom = Global.BattlegroundMgr.BGQueueTypeId(BattlegroundTypeId.RB, 0);

            // ignore if player is already in BG
            if (GetPlayer().InBattleground())
            {
                return;
            }

            // get bg instance or bg template if instance not found
            Battleground bg = Global.BattlegroundMgr.GetBattlegroundTemplate(bgTypeId);

            if (!bg)
            {
                return;
            }

            // expected bracket entry
            PvpDifficultyRecord bracketEntry = Global.DB2Mgr.GetBattlegroundBracketByLevel(bg.GetMapId(), GetPlayer().getLevel());

            if (bracketEntry == null)
            {
                return;
            }

            GroupJoinBattlegroundResult err = GroupJoinBattlegroundResult.None;

            // check queue conditions
            if (!battlemasterJoin.JoinAsGroup)
            {
                if (GetPlayer().isUsingLfg())
                {
                    Global.BattlegroundMgr.BuildBattlegroundStatusFailed(out battlefieldStatusFailed, bg, GetPlayer(), 0, 0, GroupJoinBattlegroundResult.LfgCantUseBattleground);
                    SendPacket(battlefieldStatusFailed);
                    return;
                }

                // check Deserter debuff
                if (!GetPlayer().CanJoinToBattleground(bg))
                {
                    Global.BattlegroundMgr.BuildBattlegroundStatusFailed(out battlefieldStatusFailed, bg, GetPlayer(), 0, 0, GroupJoinBattlegroundResult.Deserters);
                    SendPacket(battlefieldStatusFailed);
                    return;
                }

                if (GetPlayer().GetBattlegroundQueueIndex(bgQueueTypeIdRandom) < SharedConst.MaxPlayerBGQueues)
                {
                    // player is already in random queue
                    Global.BattlegroundMgr.BuildBattlegroundStatusFailed(out battlefieldStatusFailed, bg, GetPlayer(), 0, 0, GroupJoinBattlegroundResult.InRandomBg);
                    SendPacket(battlefieldStatusFailed);
                    return;
                }

                if (GetPlayer().InBattlegroundQueue() && bgTypeId == BattlegroundTypeId.RB)
                {
                    // player is already in queue, can't start random queue
                    Global.BattlegroundMgr.BuildBattlegroundStatusFailed(out battlefieldStatusFailed, bg, GetPlayer(), 0, 0, GroupJoinBattlegroundResult.InNonRandomBg);
                    SendPacket(battlefieldStatusFailed);
                    return;
                }

                // check if already in queue
                if (GetPlayer().GetBattlegroundQueueIndex(bgQueueTypeId) < SharedConst.MaxPlayerBGQueues)
                {
                    return;  // player is already in this queue
                }
                // check if has free queue slots
                if (!GetPlayer().HasFreeBattlegroundQueueId())
                {
                    Global.BattlegroundMgr.BuildBattlegroundStatusFailed(out battlefieldStatusFailed, bg, GetPlayer(), 0, 0, GroupJoinBattlegroundResult.TooManyQueues);
                    SendPacket(battlefieldStatusFailed);
                    return;
                }

                // check Freeze debuff
                if (_player.HasAura(9454))
                {
                    return;
                }

                BattlegroundQueue bgQueue = Global.BattlegroundMgr.GetBattlegroundQueue(bgQueueTypeId);
                GroupQueueInfo    ginfo   = bgQueue.AddGroup(GetPlayer(), null, bgTypeId, bracketEntry, 0, false, isPremade, 0, 0);

                uint avgTime   = bgQueue.GetAverageQueueWaitTime(ginfo, bracketEntry.GetBracketId());
                uint queueSlot = GetPlayer().AddBattlegroundQueueId(bgQueueTypeId);

                BattlefieldStatusQueued battlefieldStatusQueued;
                Global.BattlegroundMgr.BuildBattlegroundStatusQueued(out battlefieldStatusQueued, bg, GetPlayer(), queueSlot, ginfo.JoinTime, avgTime, ginfo.ArenaType, false);
                SendPacket(battlefieldStatusQueued);

                Log.outDebug(LogFilter.Battleground, "Battleground: player joined queue for bg queue type {0} bg type {1}: GUID {2}, NAME {3}",
                             bgQueueTypeId, bgTypeId, GetPlayer().GetGUID().ToString(), GetPlayer().GetName());
            }
            else
            {
                grp = GetPlayer().GetGroup();

                if (!grp)
                {
                    return;
                }

                if (grp.GetLeaderGUID() != GetPlayer().GetGUID())
                {
                    return;
                }

                ObjectGuid errorGuid;
                err       = grp.CanJoinBattlegroundQueue(bg, bgQueueTypeId, 0, bg.GetMaxPlayersPerTeam(), false, 0, out errorGuid);
                isPremade = (grp.GetMembersCount() >= bg.GetMinPlayersPerTeam());

                BattlegroundQueue bgQueue = Global.BattlegroundMgr.GetBattlegroundQueue(bgQueueTypeId);
                GroupQueueInfo    ginfo   = null;
                uint avgTime = 0;

                if (err == 0)
                {
                    Log.outDebug(LogFilter.Battleground, "Battleground: the following players are joining as group:");
                    ginfo   = bgQueue.AddGroup(GetPlayer(), grp, bgTypeId, bracketEntry, 0, false, isPremade, 0, 0);
                    avgTime = bgQueue.GetAverageQueueWaitTime(ginfo, bracketEntry.GetBracketId());
                }

                for (GroupReference refe = grp.GetFirstMember(); refe != null; refe = refe.next())
                {
                    Player member = refe.GetSource();
                    if (!member)
                    {
                        continue;   // this should never happen
                    }
                    if (err != 0)
                    {
                        BattlefieldStatusFailed battlefieldStatus;
                        Global.BattlegroundMgr.BuildBattlegroundStatusFailed(out battlefieldStatus, bg, GetPlayer(), 0, 0, err, errorGuid);
                        member.SendPacket(battlefieldStatus);
                        continue;
                    }

                    // add to queue
                    uint queueSlot = member.AddBattlegroundQueueId(bgQueueTypeId);

                    BattlefieldStatusQueued battlefieldStatusQueued;
                    Global.BattlegroundMgr.BuildBattlegroundStatusQueued(out battlefieldStatusQueued, bg, member, queueSlot, ginfo.JoinTime, avgTime, ginfo.ArenaType, true);
                    member.SendPacket(battlefieldStatusQueued);
                    Log.outDebug(LogFilter.Battleground, "Battleground: player joined queue for bg queue type {0} bg type {1}: GUID {2}, NAME {3}",
                                 bgQueueTypeId, bgTypeId, member.GetGUID().ToString(), member.GetName());
                }
                Log.outDebug(LogFilter.Battleground, "Battleground: group end");
            }

            Global.BattlegroundMgr.ScheduleQueueUpdate(0, 0, bgQueueTypeId, bgTypeId, bracketEntry.GetBracketId());
        }
示例#3
0
        void HandleLootMoney(LootMoney lootMoney)
        {
            Player player = GetPlayer();

            foreach (var lootView in player.GetAELootView())
            {
                ObjectGuid guid       = lootView.Value;
                Loot       loot       = null;
                bool       shareMoney = true;

                switch (guid.GetHigh())
                {
                case HighGuid.GameObject:
                {
                    GameObject go = player.GetMap().GetGameObject(guid);

                    // do not check distance for GO if player is the owner of it (ex. fishing bobber)
                    if (go && ((go.GetOwnerGUID() == player.GetGUID() || go.IsWithinDistInMap(player, SharedConst.InteractionDistance))))
                    {
                        loot = go.loot;
                    }

                    break;
                }

                case HighGuid.Corpse:                                   // remove insignia ONLY in BG
                {
                    Corpse bones = ObjectAccessor.GetCorpse(player, guid);

                    if (bones && bones.IsWithinDistInMap(player, SharedConst.InteractionDistance))
                    {
                        loot       = bones.loot;
                        shareMoney = false;
                    }

                    break;
                }

                case HighGuid.Item:
                {
                    Item item = player.GetItemByGuid(guid);
                    if (item)
                    {
                        loot       = item.loot;
                        shareMoney = false;
                    }
                    break;
                }

                case HighGuid.Creature:
                case HighGuid.Vehicle:
                {
                    Creature creature    = player.GetMap().GetCreature(guid);
                    bool     lootAllowed = creature && creature.IsAlive() == (player.GetClass() == Class.Rogue && creature.loot.loot_type == LootType.Pickpocketing);
                    if (lootAllowed && creature.IsWithinDistInMap(player, AELootCreatureCheck.LootDistance))
                    {
                        loot = creature.loot;
                        if (creature.IsAlive())
                        {
                            shareMoney = false;
                        }
                    }
                    else
                    {
                        player.SendLootError(lootView.Key, guid, lootAllowed ? LootError.TooFar : LootError.DidntKill);
                    }
                    break;
                }

                default:
                    continue;                                             // unlootable type
                }

                if (loot == null)
                {
                    continue;
                }

                loot.NotifyMoneyRemoved();
                if (shareMoney && player.GetGroup() != null)      //item, pickpocket and players can be looted only single player
                {
                    Group group = player.GetGroup();

                    List <Player> playersNear = new();
                    for (GroupReference refe = group.GetFirstMember(); refe != null; refe = refe.Next())
                    {
                        Player member = refe.GetSource();
                        if (!member)
                        {
                            continue;
                        }

                        if (player.IsAtGroupRewardDistance(member))
                        {
                            playersNear.Add(member);
                        }
                    }

                    ulong goldPerPlayer = (ulong)(loot.gold / playersNear.Count);

                    foreach (var pl in playersNear)
                    {
                        ulong goldMod = MathFunctions.CalculatePct(goldPerPlayer, pl.GetTotalAuraModifierByMiscValue(AuraType.ModMoneyGain, 1));

                        pl.ModifyMoney((long)(goldPerPlayer + goldMod));
                        pl.UpdateCriteria(CriteriaTypes.LootMoney, goldPerPlayer);

                        LootMoneyNotify packet = new();
                        packet.Money      = goldPerPlayer;
                        packet.MoneyMod   = goldMod;
                        packet.SoleLooter = playersNear.Count <= 1 ? true : false;
                        pl.SendPacket(packet);
                    }
                }
                else
                {
                    ulong goldMod = MathFunctions.CalculatePct(loot.gold, player.GetTotalAuraModifierByMiscValue(AuraType.ModMoneyGain, 1));

                    player.ModifyMoney((long)(loot.gold + goldMod));
                    player.UpdateCriteria(CriteriaTypes.LootMoney, loot.gold);

                    LootMoneyNotify packet = new();
                    packet.Money      = loot.gold;
                    packet.MoneyMod   = goldMod;
                    packet.SoleLooter = true; // "You loot..."
                    SendPacket(packet);
                }

                loot.gold = 0;

                // Delete the money loot record from the DB
                if (!loot.containerID.IsEmpty())
                {
                    Global.LootItemStorage.RemoveStoredMoneyForContainer(loot.containerID.GetCounter());
                }

                // Delete container if empty
                if (loot.IsLooted() && guid.IsItem())
                {
                    player.GetSession().DoLootRelease(guid);
                }
            }
        }
示例#4
0
        public void DoLootRelease(ObjectGuid lguid)
        {
            Player player = GetPlayer();
            Loot   loot;

            if (player.GetLootGUID() == lguid)
            {
                player.SetLootGUID(ObjectGuid.Empty);
            }

            player.SendLootRelease(lguid);
            player.RemoveAELootedWorldObject(lguid);

            player.RemoveUnitFlag(UnitFlags.Looting);

            if (!player.IsInWorld)
            {
                return;
            }

            if (lguid.IsGameObject())
            {
                GameObject go = player.GetMap().GetGameObject(lguid);

                // not check distance for GO in case owned GO (fishing bobber case, for example) or Fishing hole GO
                if (!go || ((go.GetOwnerGUID() != player.GetGUID() && go.GetGoType() != GameObjectTypes.FishingHole) && !go.IsWithinDistInMap(player, SharedConst.InteractionDistance)))
                {
                    return;
                }

                loot = go.loot;

                if (go.GetGoType() == GameObjectTypes.Door)
                {
                    // locked doors are opened with spelleffect openlock, prevent remove its as looted
                    go.UseDoorOrButton();
                }
                else if (loot.IsLooted() || go.GetGoType() == GameObjectTypes.FishingNode)
                {
                    if (go.GetGoType() == GameObjectTypes.FishingHole)
                    {                                              // The fishing hole used once more
                        go.AddUse();                               // if the max usage is reached, will be despawned in next tick
                        if (go.GetUseCount() >= go.GetGoValue().FishingHole.MaxOpens)
                        {
                            go.SetLootState(LootState.JustDeactivated);
                        }
                        else
                        {
                            go.SetLootState(LootState.Ready);
                        }
                    }
                    else
                    {
                        go.SetLootState(LootState.JustDeactivated);
                    }

                    loot.Clear();
                }
                else
                {
                    // not fully looted object
                    go.SetLootState(LootState.Activated, player);

                    // if the round robin player release, reset it.
                    if (player.GetGUID() == loot.roundRobinPlayer)
                    {
                        loot.roundRobinPlayer.Clear();
                    }
                }
            }
            else if (lguid.IsCorpse())        // ONLY remove insignia at BG
            {
                Corpse corpse = ObjectAccessor.GetCorpse(player, lguid);
                if (!corpse || !corpse.IsWithinDistInMap(player, SharedConst.InteractionDistance))
                {
                    return;
                }

                loot = corpse.loot;

                if (loot.IsLooted())
                {
                    loot.Clear();
                    corpse.RemoveCorpseDynamicFlag(CorpseDynFlags.Lootable);
                }
            }
            else if (lguid.IsItem())
            {
                Item pItem = player.GetItemByGuid(lguid);
                if (!pItem)
                {
                    return;
                }

                ItemTemplate proto = pItem.GetTemplate();

                // destroy only 5 items from stack in case prospecting and milling
                if (pItem.loot.loot_type == LootType.Prospecting || pItem.loot.loot_type == LootType.Milling)
                {
                    pItem.m_lootGenerated = false;
                    pItem.loot.Clear();

                    uint count = pItem.GetCount();

                    // >=5 checked in spell code, but will work for cheating cases also with removing from another stacks.
                    if (count > 5)
                    {
                        count = 5;
                    }

                    player.DestroyItemCount(pItem, ref count, true);
                }
                else
                {
                    if (pItem.loot.IsLooted() || !proto.GetFlags().HasAnyFlag(ItemFlags.HasLoot)) // Only delete item if no loot or money (unlooted loot is saved to db)
                    {
                        player.DestroyItem(pItem.GetBagSlot(), pItem.GetSlot(), true);
                    }
                }
                return;                                             // item can be looted only single player
            }
            else
            {
                Creature creature = player.GetMap().GetCreature(lguid);

                bool lootAllowed = creature && creature.IsAlive() == (player.GetClass() == Class.Rogue && creature.loot.loot_type == LootType.Pickpocketing);
                if (!lootAllowed || !creature.IsWithinDistInMap(player, AELootCreatureCheck.LootDistance))
                {
                    return;
                }

                loot = creature.loot;
                if (loot.IsLooted())
                {
                    creature.RemoveDynamicFlag(UnitDynFlags.Lootable);

                    // skip pickpocketing loot for speed, skinning timer reduction is no-op in fact
                    if (!creature.IsAlive())
                    {
                        creature.AllLootRemovedFromCorpse();
                    }

                    loot.Clear();
                }
                else
                {
                    // if the round robin player release, reset it.
                    if (player.GetGUID() == loot.roundRobinPlayer)
                    {
                        loot.roundRobinPlayer.Clear();

                        Group group = player.GetGroup();
                        if (group)
                        {
                            if (group.GetLootMethod() != LootMethod.MasterLoot)
                            {
                                group.SendLooter(creature, null);
                            }
                        }
                        // force dynflag update to update looter and lootable info
                        creature.m_values.ModifyValue(creature.m_objectData).ModifyValue(creature.m_objectData.DynamicFlags);
                        creature.ForceUpdateFieldChange();
                    }
                }
            }

            //Player is not looking at loot list, he doesn't need to see updates on the loot list
            loot.RemoveLooter(player.GetGUID());
        }
示例#5
0
        void HandleSetRaidDifficulty(SetRaidDifficulty setRaidDifficulty)
        {
            DifficultyRecord difficultyEntry = CliDB.DifficultyStorage.LookupByKey(setRaidDifficulty.DifficultyID);

            if (difficultyEntry == null)
            {
                Log.outDebug(LogFilter.Network, "WorldSession.HandleSetDungeonDifficulty: {0} sent an invalid instance mode {1}!",
                             GetPlayer().GetGUID().ToString(), setRaidDifficulty.DifficultyID);
                return;
            }

            if (difficultyEntry.InstanceType != MapTypes.Raid)
            {
                Log.outDebug(LogFilter.Network, "WorldSession.HandleSetDungeonDifficulty: {0} sent an non-dungeon instance mode {1}!",
                             GetPlayer().GetGUID().ToString(), difficultyEntry.Id);
                return;
            }

            if (!difficultyEntry.Flags.HasAnyFlag(DifficultyFlags.CanSelect))
            {
                Log.outDebug(LogFilter.Network, "WorldSession.HandleSetDungeonDifficulty: {0} sent unselectable instance mode {1}!",
                             GetPlayer().GetGUID().ToString(), difficultyEntry.Id);
                return;
            }

            if (((int)(difficultyEntry.Flags & DifficultyFlags.Legacy) >> 5) != setRaidDifficulty.Legacy)
            {
                Log.outDebug(LogFilter.Network, "WorldSession.HandleSetDungeonDifficulty: {0} sent not matching legacy difficulty {1}!",
                             GetPlayer().GetGUID().ToString(), difficultyEntry.Id);
                return;
            }

            Difficulty difficultyID = (Difficulty)difficultyEntry.Id;

            if (difficultyID == (setRaidDifficulty.Legacy != 0 ? GetPlayer().GetLegacyRaidDifficultyID() : GetPlayer().GetRaidDifficultyID()))
            {
                return;
            }

            // cannot reset while in an instance
            Map map = GetPlayer().GetMap();

            if (map && map.IsDungeon())
            {
                Log.outDebug(LogFilter.Network, "WorldSession:HandleSetRaidDifficulty: player (Name: {0}, {1} tried to reset the instance while inside!",
                             GetPlayer().GetName(), GetPlayer().GetGUID().ToString());
                return;
            }

            Group group = GetPlayer().GetGroup();

            if (group)
            {
                if (group.IsLeader(GetPlayer().GetGUID()))
                {
                    for (GroupReference refe = group.GetFirstMember(); refe != null; refe = refe.Next())
                    {
                        Player groupGuy = refe.GetSource();
                        if (!groupGuy)
                        {
                            continue;
                        }

                        if (!groupGuy.IsInMap(groupGuy))
                        {
                            return;
                        }

                        if (groupGuy.GetMap().IsRaid())
                        {
                            Log.outDebug(LogFilter.Network, "WorldSession:HandleSetRaidDifficulty: player {0} tried to reset the instance while inside!", GetPlayer().GetGUID().ToString());
                            return;
                        }
                    }
                    // the difficulty is set even if the instances can't be reset
                    group.ResetInstances(InstanceResetMethod.ChangeDifficulty, true, setRaidDifficulty.Legacy != 0, GetPlayer());
                    if (setRaidDifficulty.Legacy != 0)
                    {
                        group.SetLegacyRaidDifficultyID(difficultyID);
                    }
                    else
                    {
                        group.SetRaidDifficultyID(difficultyID);
                    }
                }
            }
            else
            {
                GetPlayer().ResetInstances(InstanceResetMethod.ChangeDifficulty, true, setRaidDifficulty.Legacy != 0);
                if (setRaidDifficulty.Legacy != 0)
                {
                    GetPlayer().SetLegacyRaidDifficultyID(difficultyID);
                }
                else
                {
                    GetPlayer().SetRaidDifficultyID(difficultyID);
                }

                GetPlayer().SendRaidDifficulty(setRaidDifficulty.Legacy != 0);
            }
        }
示例#6
0
        void HandleSetDungeonDifficulty(SetDungeonDifficulty setDungeonDifficulty)
        {
            DifficultyRecord difficultyEntry = CliDB.DifficultyStorage.LookupByKey(setDungeonDifficulty.DifficultyID);

            if (difficultyEntry == null)
            {
                Log.outDebug(LogFilter.Network, "WorldSession.HandleSetDungeonDifficulty: {0} sent an invalid instance mode {1}!",
                             GetPlayer().GetGUID().ToString(), setDungeonDifficulty.DifficultyID);
                return;
            }

            if (difficultyEntry.InstanceType != MapTypes.Instance)
            {
                Log.outDebug(LogFilter.Network, "WorldSession.HandleSetDungeonDifficulty: {0} sent an non-dungeon instance mode {1}!",
                             GetPlayer().GetGUID().ToString(), difficultyEntry.Id);
                return;
            }

            if (!difficultyEntry.Flags.HasAnyFlag(DifficultyFlags.CanSelect))
            {
                Log.outDebug(LogFilter.Network, "WorldSession.HandleSetDungeonDifficulty: {0} sent unselectable instance mode {1}!",
                             GetPlayer().GetGUID().ToString(), difficultyEntry.Id);
                return;
            }

            Difficulty difficultyID = (Difficulty)difficultyEntry.Id;

            if (difficultyID == GetPlayer().GetDungeonDifficultyID())
            {
                return;
            }

            // cannot reset while in an instance
            Map map = GetPlayer().GetMap();

            if (map && map.IsDungeon())
            {
                Log.outDebug(LogFilter.Network, "WorldSession:HandleSetDungeonDifficulty: player (Name: {0}, {1}) tried to reset the instance while player is inside!",
                             GetPlayer().GetName(), GetPlayer().GetGUID().ToString());
                return;
            }

            Group group = GetPlayer().GetGroup();

            if (group)
            {
                if (group.IsLeader(GetPlayer().GetGUID()))
                {
                    for (GroupReference refe = group.GetFirstMember(); refe != null; refe = refe.Next())
                    {
                        Player groupGuy = refe.GetSource();
                        if (!groupGuy)
                        {
                            continue;
                        }

                        if (!groupGuy.IsInMap(groupGuy))
                        {
                            return;
                        }

                        if (groupGuy.GetMap().IsNonRaidDungeon())
                        {
                            Log.outDebug(LogFilter.Network, "WorldSession:HandleSetDungeonDifficulty: {0} tried to reset the instance while group member (Name: {1}, {2}) is inside!",
                                         GetPlayer().GetGUID().ToString(), groupGuy.GetName(), groupGuy.GetGUID().ToString());
                            return;
                        }
                    }
                    // the difficulty is set even if the instances can't be reset
                    //_player.SendDungeonDifficulty(true);
                    group.ResetInstances(InstanceResetMethod.ChangeDifficulty, false, false, GetPlayer());
                    group.SetDungeonDifficultyID(difficultyID);
                }
            }
            else
            {
                GetPlayer().ResetInstances(InstanceResetMethod.ChangeDifficulty, false, false);
                GetPlayer().SetDungeonDifficultyID(difficultyID);
                GetPlayer().SendDungeonDifficulty();
            }
        }
示例#7
0
        void HandleAreaTrigger(AreaTriggerPkt packet)
        {
            Player player = GetPlayer();

            if (player.IsInFlight())
            {
                Log.outDebug(LogFilter.Network, "HandleAreaTriggerOpcode: Player '{0}' (GUID: {1}) in flight, ignore Area Trigger ID:{2}",
                             player.GetName(), player.GetGUID().ToString(), packet.AreaTriggerID);
                return;
            }

            AreaTriggerRecord atEntry = CliDB.AreaTriggerStorage.LookupByKey(packet.AreaTriggerID);

            if (atEntry == null)
            {
                Log.outDebug(LogFilter.Network, "HandleAreaTriggerOpcode: Player '{0}' (GUID: {1}) send unknown (by DBC) Area Trigger ID:{2}",
                             player.GetName(), player.GetGUID().ToString(), packet.AreaTriggerID);
                return;
            }

            if (packet.Entered && !player.IsInAreaTriggerRadius(atEntry))
            {
                Log.outDebug(LogFilter.Network, "HandleAreaTriggerOpcode: Player '{0}' ({1}) too far, ignore Area Trigger ID: {2}",
                             player.GetName(), player.GetGUID().ToString(), packet.AreaTriggerID);
                return;
            }

            if (player.IsDebugAreaTriggers)
            {
                player.SendSysMessage(packet.Entered ? CypherStrings.DebugAreatriggerEntered : CypherStrings.DebugAreatriggerLeft, packet.AreaTriggerID);
            }

            if (Global.ScriptMgr.OnAreaTrigger(player, atEntry, packet.Entered))
            {
                return;
            }

            if (player.IsAlive())
            {
                List <uint> quests = Global.ObjectMgr.GetQuestsForAreaTrigger(packet.AreaTriggerID);
                if (quests != null)
                {
                    foreach (uint questId in quests)
                    {
                        Quest qInfo = Global.ObjectMgr.GetQuestTemplate(questId);
                        if (qInfo != null && player.GetQuestStatus(questId) == QuestStatus.Incomplete)
                        {
                            foreach (QuestObjective obj in qInfo.Objectives)
                            {
                                if (obj.Type == QuestObjectiveType.AreaTrigger && !player.IsQuestObjectiveComplete(obj))
                                {
                                    player.SetQuestObjectiveData(obj, 1);
                                    player.SendQuestUpdateAddCreditSimple(obj);
                                    break;
                                }
                            }

                            if (player.CanCompleteQuest(questId))
                            {
                                player.CompleteQuest(questId);
                            }
                        }
                    }
                }
            }

            if (Global.ObjectMgr.IsTavernAreaTrigger(packet.AreaTriggerID))
            {
                // set resting flag we are in the inn
                player.GetRestMgr().SetRestFlag(RestFlag.Tavern, atEntry.Id);

                if (Global.WorldMgr.IsFFAPvPRealm())
                {
                    player.RemovePvpFlag(UnitPVPStateFlags.FFAPvp);
                }

                return;
            }
            Battleground bg = player.GetBattleground();

            if (bg)
            {
                bg.HandleAreaTrigger(player, packet.AreaTriggerID, packet.Entered);
            }

            OutdoorPvP pvp = player.GetOutdoorPvP();

            if (pvp != null)
            {
                if (pvp.HandleAreaTrigger(player, packet.AreaTriggerID, packet.Entered))
                {
                    return;
                }
            }

            AreaTriggerStruct at = Global.ObjectMgr.GetAreaTrigger(packet.AreaTriggerID);

            if (at == null)
            {
                return;
            }

            bool teleported = false;

            if (player.GetMapId() != at.target_mapId)
            {
                EnterState denyReason = Global.MapMgr.PlayerCannotEnter(at.target_mapId, player, false);
                if (denyReason != 0)
                {
                    bool reviveAtTrigger = false; // should we revive the player if he is trying to enter the correct instance?
                    switch (denyReason)
                    {
                    case EnterState.CannotEnterNoEntry:
                        Log.outDebug(LogFilter.Maps, "MAP: Player '{0}' attempted to enter map with id {1} which has no entry", player.GetName(), at.target_mapId);
                        break;

                    case EnterState.CannotEnterUninstancedDungeon:
                        Log.outDebug(LogFilter.Maps, "MAP: Player '{0}' attempted to enter dungeon map {1} but no instance template was found", player.GetName(), at.target_mapId);
                        break;

                    case EnterState.CannotEnterDifficultyUnavailable:
                    {
                        Log.outDebug(LogFilter.Maps, "MAP: Player '{0}' attempted to enter instance map {1} but the requested difficulty was not found", player.GetName(), at.target_mapId);
                        MapRecord entry = CliDB.MapStorage.LookupByKey(at.target_mapId);
                        if (entry != null)
                        {
                            player.SendTransferAborted(entry.Id, TransferAbortReason.Difficulty, (byte)player.GetDifficultyID(entry));
                        }
                    }
                    break;

                    case EnterState.CannotEnterNotInRaid:
                        Log.outDebug(LogFilter.Maps, "MAP: Player '{0}' must be in a raid group to enter map {1}", player.GetName(), at.target_mapId);
                        player.SendRaidGroupOnlyMessage(RaidGroupReason.Only, 0);
                        reviveAtTrigger = true;
                        break;

                    case EnterState.CannotEnterCorpseInDifferentInstance:
                        player.SendPacket(new AreaTriggerNoCorpse());
                        Log.outDebug(LogFilter.Maps, "MAP: Player '{0}' does not have a corpse in instance map {1} and cannot enter", player.GetName(), at.target_mapId);
                        break;

                    case EnterState.CannotEnterInstanceBindMismatch:
                    {
                        MapRecord entry = CliDB.MapStorage.LookupByKey(at.target_mapId);
                        if (entry != null)
                        {
                            string mapName = entry.MapName[player.GetSession().GetSessionDbcLocale()];
                            Log.outDebug(LogFilter.Maps, "MAP: Player '{0}' cannot enter instance map '{1}' because their permanent bind is incompatible with their group's", player.GetName(), mapName);
                            // is there a special opcode for this?
                            // @todo figure out how to get player localized difficulty string (e.g. "10 player", "Heroic" etc)
                            player.SendSysMessage(CypherStrings.InstanceBindMismatch, mapName);
                        }
                        reviveAtTrigger = true;
                    }
                    break;

                    case EnterState.CannotEnterTooManyInstances:
                        player.SendTransferAborted(at.target_mapId, TransferAbortReason.TooManyInstances);
                        Log.outDebug(LogFilter.Maps, "MAP: Player '{0}' cannot enter instance map {1} because he has exceeded the maximum number of instances per hour.", player.GetName(), at.target_mapId);
                        reviveAtTrigger = true;
                        break;

                    case EnterState.CannotEnterMaxPlayers:
                        player.SendTransferAborted(at.target_mapId, TransferAbortReason.MaxPlayers);
                        reviveAtTrigger = true;
                        break;

                    case EnterState.CannotEnterZoneInCombat:
                        player.SendTransferAborted(at.target_mapId, TransferAbortReason.ZoneInCombat);
                        reviveAtTrigger = true;
                        break;

                    default:
                        break;
                    }

                    if (reviveAtTrigger) // check if the player is touching the areatrigger leading to the map his corpse is on
                    {
                        if (!player.IsAlive() && player.HasCorpse())
                        {
                            if (player.GetCorpseLocation().GetMapId() == at.target_mapId)
                            {
                                player.ResurrectPlayer(0.5f);
                                player.SpawnCorpseBones();
                            }
                        }
                    }

                    return;
                }

                Group group = player.GetGroup();
                if (group)
                {
                    if (group.IsLFGGroup() && player.GetMap().IsDungeon())
                    {
                        teleported = player.TeleportToBGEntryPoint();
                    }
                }
            }

            if (!teleported)
            {
                WorldSafeLocsEntry entranceLocation = null;
                InstanceSave       instanceSave     = player.GetInstanceSave(at.target_mapId);
                if (instanceSave != null)
                {
                    // Check if we can contact the instancescript of the instance for an updated entrance location
                    Map map = Global.MapMgr.FindMap(at.target_mapId, player.GetInstanceSave(at.target_mapId).GetInstanceId());
                    if (map)
                    {
                        InstanceMap instanceMap = map.ToInstanceMap();
                        if (instanceMap != null)
                        {
                            InstanceScript instanceScript = instanceMap.GetInstanceScript();
                            if (instanceScript != null)
                            {
                                entranceLocation = Global.ObjectMgr.GetWorldSafeLoc(instanceScript.GetEntranceLocation());
                            }
                        }
                    }

                    // Finally check with the instancesave for an entrance location if we did not get a valid one from the instancescript
                    if (entranceLocation == null)
                    {
                        entranceLocation = Global.ObjectMgr.GetWorldSafeLoc(instanceSave.GetEntranceLocation());
                    }
                }

                if (entranceLocation != null)
                {
                    player.TeleportTo(entranceLocation.Loc, TeleportToOptions.NotLeaveTransport);
                }
                else
                {
                    player.TeleportTo(at.target_mapId, at.target_X, at.target_Y, at.target_Z, at.target_Orientation, TeleportToOptions.NotLeaveTransport);
                }
            }
        }
示例#8
0
        void HandlePartyInvite(PartyInviteClient packet)
        {
            Player player = Global.ObjAccessor.FindPlayerByName(packet.TargetName);

            // no player
            if (!player)
            {
                SendPartyResult(PartyOperation.Invite, packet.TargetName, PartyResult.BadPlayerNameS);
                return;
            }

            // player trying to invite himself (most likely cheating)
            if (player == GetPlayer())
            {
                SendPartyResult(PartyOperation.Invite, player.GetName(), PartyResult.BadPlayerNameS);
                return;
            }

            // restrict invite to GMs
            if (!WorldConfig.GetBoolValue(WorldCfg.AllowGmGroup) && !GetPlayer().IsGameMaster() && player.IsGameMaster())
            {
                SendPartyResult(PartyOperation.Invite, player.GetName(), PartyResult.BadPlayerNameS);
                return;
            }

            // can't group with
            if (!GetPlayer().IsGameMaster() && !WorldConfig.GetBoolValue(WorldCfg.AllowTwoSideInteractionGroup) && GetPlayer().GetTeam() != player.GetTeam())
            {
                SendPartyResult(PartyOperation.Invite, player.GetName(), PartyResult.PlayerWrongFaction);
                return;
            }
            if (GetPlayer().GetInstanceId() != 0 && player.GetInstanceId() != 0 && GetPlayer().GetInstanceId() != player.GetInstanceId() && GetPlayer().GetMapId() == player.GetMapId())
            {
                SendPartyResult(PartyOperation.Invite, player.GetName(), PartyResult.TargetNotInInstanceS);
                return;
            }
            // just ignore us
            if (player.GetInstanceId() != 0 && player.GetDungeonDifficultyID() != GetPlayer().GetDungeonDifficultyID())
            {
                SendPartyResult(PartyOperation.Invite, player.GetName(), PartyResult.IgnoringYouS);
                return;
            }

            if (player.GetSocial().HasIgnore(GetPlayer().GetGUID()))
            {
                SendPartyResult(PartyOperation.Invite, player.GetName(), PartyResult.IgnoringYouS);
                return;
            }

            if (!player.GetSocial().HasFriend(GetPlayer().GetGUID()) && GetPlayer().getLevel() < WorldConfig.GetIntValue(WorldCfg.PartyLevelReq))
            {
                SendPartyResult(PartyOperation.Invite, player.GetName(), PartyResult.InviteRestricted);
                return;
            }

            Group group = GetPlayer().GetGroup();

            if (group && group.isBGGroup())
            {
                group = GetPlayer().GetOriginalGroup();
            }

            Group group2 = player.GetGroup();

            if (group2 && group2.isBGGroup())
            {
                group2 = player.GetOriginalGroup();
            }

            PartyInvite partyInvite;

            // player already in another group or invited
            if (group2 || player.GetGroupInvite())
            {
                SendPartyResult(PartyOperation.Invite, player.GetName(), PartyResult.AlreadyInGroupS);

                if (group2)
                {
                    // tell the player that they were invited but it failed as they were already in a group
                    partyInvite = new PartyInvite();
                    partyInvite.Initialize(GetPlayer(), packet.ProposedRoles, false);
                    player.SendPacket(partyInvite);
                }

                return;
            }

            if (group)
            {
                // not have permissions for invite
                if (!group.IsLeader(GetPlayer().GetGUID()) && !group.IsAssistant(GetPlayer().GetGUID()))
                {
                    SendPartyResult(PartyOperation.Invite, "", PartyResult.NotLeader);
                    return;
                }
                // not have place
                if (group.IsFull())
                {
                    SendPartyResult(PartyOperation.Invite, "", PartyResult.GroupFull);
                    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()))
                {
                    return;
                }

                if (!group.AddInvite(player))
                {
                    group.RemoveAllInvites();
                    return;
                }
            }
            else
            {
                // already existed group: if can't add then just leave
                if (!group.AddInvite(player))
                {
                    return;
                }
            }

            partyInvite = new PartyInvite();
            partyInvite.Initialize(GetPlayer(), packet.ProposedRoles, true);
            player.SendPacket(partyInvite);

            SendPartyResult(PartyOperation.Invite, player.GetName(), PartyResult.Ok);
        }
示例#9
0
        void HandlePartyInviteResponse(PartyInviteResponse packet)
        {
            Group group = GetPlayer().GetGroupInvite();

            if (!group)
            {
                return;
            }

            if (packet.Accept)
            {
                // Remove player from invitees in any case
                group.RemoveInvite(GetPlayer());

                if (group.GetLeaderGUID() == GetPlayer().GetGUID())
                {
                    Log.outError(LogFilter.Network, "HandleGroupAcceptOpcode: player {0} ({1}) tried to accept an invite to his own group", GetPlayer().GetName(), GetPlayer().GetGUID().ToString());
                    return;
                }

                // Group is full
                if (group.IsFull())
                {
                    SendPartyResult(PartyOperation.Invite, "", PartyResult.GroupFull);
                    return;
                }

                Player leader = Global.ObjAccessor.FindPlayer(group.GetLeaderGUID());

                // Forming a new group, create it
                if (!group.IsCreated())
                {
                    // This can happen if the leader is zoning. To be removed once delayed actions for zoning are implemented
                    if (!leader)
                    {
                        group.RemoveAllInvites();
                        return;
                    }

                    // If we're about to create a group there really should be a leader present
                    Cypher.Assert(leader);
                    group.RemoveInvite(leader);
                    group.Create(leader);
                    Global.GroupMgr.AddGroup(group);
                }

                // Everything is fine, do it, PLAYER'S GROUP IS SET IN ADDMEMBER!!!
                if (!group.AddMember(GetPlayer()))
                {
                    return;
                }

                group.BroadcastGroupUpdate();
            }
            else
            {
                // Remember leader if online (group will be invalid if group gets disbanded)
                Player leader = Global.ObjAccessor.FindPlayer(group.GetLeaderGUID());

                // uninvite, group can be deleted
                GetPlayer().UninviteFromGroup();

                if (!leader || leader.GetSession() == null)
                {
                    return;
                }

                // report
                GroupDecline decline = new GroupDecline(GetPlayer().GetName());
                leader.SendPacket(decline);
            }
        }