Exemple #1
0
        void HandlePetSpellAutocast(PetSpellAutocast packet)
        {
            Creature pet = ObjectAccessor.GetCreatureOrPetOrVehicle(GetPlayer(), packet.PetGUID);

            if (!pet)
            {
                Log.outError(LogFilter.Network, "WorldSession.HandlePetSpellAutocast: {0} not found.", packet.PetGUID.ToString());
                return;
            }

            if (pet != GetPlayer().GetGuardianPet() && pet != GetPlayer().GetCharmed())
            {
                Log.outError(LogFilter.Network, "WorldSession.HandlePetSpellAutocast: {0} isn't pet of player {1} ({2}).",
                             packet.PetGUID.ToString(), GetPlayer().GetName(), GetPlayer().GetGUID().ToString());
                return;
            }

            SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(packet.SpellID, pet.GetMap().GetDifficultyID());

            if (spellInfo == null)
            {
                Log.outError(LogFilter.Network, "WorldSession.HandlePetSpellAutocast: Unknown spell id {0} used by {1}.", packet.SpellID, packet.PetGUID.ToString());
                return;
            }

            List <Unit> pets = new();

            foreach (Unit controlled in _player.m_Controlled)
            {
                if (controlled.GetEntry() == pet.GetEntry() && controlled.IsAlive())
                {
                    pets.Add(controlled);
                }
            }

            foreach (Unit petControlled in pets)
            {
                // do not add not learned spells/ passive spells
                if (!petControlled.HasSpell(packet.SpellID) || !spellInfo.IsAutocastable())
                {
                    return;
                }

                CharmInfo charmInfo = petControlled.GetCharmInfo();
                if (charmInfo == null)
                {
                    Log.outError(LogFilter.Network, "WorldSession.HandlePetSpellAutocastOpcod: object {0} is considered pet-like but doesn't have a charminfo!", petControlled.GetGUID().ToString());
                    return;
                }

                if (petControlled.IsPet())
                {
                    petControlled.ToPet().ToggleAutocast(spellInfo, packet.AutocastEnabled);
                }
                else
                {
                    charmInfo.ToggleCreatureAutocast(spellInfo, packet.AutocastEnabled);
                }

                charmInfo.SetSpellAutocast(spellInfo, packet.AutocastEnabled);
            }
        }
Exemple #2
0
        void moveItems(Item[] myItems, Item[] hisItems)
        {
            Player trader = GetPlayer().GetTrader();

            if (!trader)
            {
                return;
            }

            for (byte i = 0; i < (int)TradeSlots.TradedCount; ++i)
            {
                List <ItemPosCount> traderDst = new List <ItemPosCount>();
                List <ItemPosCount> playerDst = new List <ItemPosCount>();
                bool traderCanTrade           = (myItems[i] == null || trader.CanStoreItem(ItemConst.NullBag, ItemConst.NullSlot, traderDst, myItems[i], false) == InventoryResult.Ok);
                bool playerCanTrade           = (hisItems[i] == null || GetPlayer().CanStoreItem(ItemConst.NullBag, ItemConst.NullSlot, playerDst, hisItems[i], false) == InventoryResult.Ok);
                if (traderCanTrade && playerCanTrade)
                {
                    // Ok, if trade item exists and can be stored
                    // If we trade in both directions we had to check, if the trade will work before we actually do it
                    // A roll back is not possible after we stored it
                    if (myItems[i])
                    {
                        // logging
                        Log.outDebug(LogFilter.Network, "partner storing: {0}", myItems[i].GetGUID().ToString());

                        if (HasPermission(RBACPermissions.LogGmTrade))
                        {
                            Log.outCommand(_player.GetSession().GetAccountId(), "GM {0} (Account: {1}) trade: {2} (Entry: {3} Count: {4}) to player: {5} (Account: {6})",
                                           GetPlayer().GetName(), GetPlayer().GetSession().GetAccountId(), myItems[i].GetTemplate().GetName(), myItems[i].GetEntry(), myItems[i].GetCount(),
                                           trader.GetName(), trader.GetSession().GetAccountId());
                        }

                        // adjust time (depends on /played)
                        if (myItems[i].HasItemFlag(ItemFieldFlags.BopTradeable))
                        {
                            myItems[i].SetCreatePlayedTime(trader.GetTotalPlayedTime() - (GetPlayer().GetTotalPlayedTime() - myItems[i].m_itemData.CreatePlayedTime));
                        }
                        // store
                        trader.MoveItemToInventory(traderDst, myItems[i], true, true);
                    }
                    if (hisItems[i])
                    {
                        // logging
                        Log.outDebug(LogFilter.Network, "player storing: {0}", hisItems[i].GetGUID().ToString());

                        if (HasPermission(RBACPermissions.LogGmTrade))
                        {
                            Log.outCommand(trader.GetSession().GetAccountId(), "GM {0} (Account: {1}) trade: {2} (Entry: {3} Count: {4}) to player: {5} (Account: {6})",
                                           trader.GetName(), trader.GetSession().GetAccountId(), hisItems[i].GetTemplate().GetName(), hisItems[i].GetEntry(), hisItems[i].GetCount(),
                                           GetPlayer().GetName(), GetPlayer().GetSession().GetAccountId());
                        }


                        // adjust time (depends on /played)
                        if (hisItems[i].HasItemFlag(ItemFieldFlags.BopTradeable))
                        {
                            hisItems[i].SetCreatePlayedTime(GetPlayer().GetTotalPlayedTime() - (trader.GetTotalPlayedTime() - hisItems[i].m_itemData.CreatePlayedTime));
                        }
                        // store
                        GetPlayer().MoveItemToInventory(playerDst, hisItems[i], true, true);
                    }
                }
                else
                {
                    // in case of fatal error log error message
                    // return the already removed items to the original owner
                    if (myItems[i])
                    {
                        if (!traderCanTrade)
                        {
                            Log.outError(LogFilter.Network, "trader can't store item: {0}", myItems[i].GetGUID().ToString());
                        }
                        if (GetPlayer().CanStoreItem(ItemConst.NullBag, ItemConst.NullSlot, playerDst, myItems[i], false) == InventoryResult.Ok)
                        {
                            GetPlayer().MoveItemToInventory(playerDst, myItems[i], true, true);
                        }
                        else
                        {
                            Log.outError(LogFilter.Network, "player can't take item back: {0}", myItems[i].GetGUID().ToString());
                        }
                    }
                    // return the already removed items to the original owner
                    if (hisItems[i])
                    {
                        if (!playerCanTrade)
                        {
                            Log.outError(LogFilter.Network, "player can't store item: {0}", hisItems[i].GetGUID().ToString());
                        }
                        if (trader.CanStoreItem(ItemConst.NullBag, ItemConst.NullSlot, traderDst, hisItems[i], false) == InventoryResult.Ok)
                        {
                            trader.MoveItemToInventory(traderDst, hisItems[i], true, true);
                        }
                        else
                        {
                            Log.outError(LogFilter.Network, "trader can't take item back: {0}", hisItems[i].GetGUID().ToString());
                        }
                    }
                }
            }
        }
        void HandleCastSpell(CastSpell cast)
        {
            // ignore for remote control state (for player case)
            Unit mover = GetPlayer().m_unitMovedByMe;

            if (mover != GetPlayer() && mover.IsTypeId(TypeId.Player))
            {
                return;
            }

            SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(cast.Cast.SpellID);

            if (spellInfo == null)
            {
                Log.outError(LogFilter.Network, "WORLD: unknown spell id {0}", cast.Cast.SpellID);
                return;
            }

            if (spellInfo.IsPassive())
            {
                return;
            }

            Unit caster = mover;

            if (caster.IsTypeId(TypeId.Unit) && !caster.ToCreature().HasSpell(spellInfo.Id))
            {
                // If the vehicle creature does not have the spell but it allows the passenger to cast own spells
                // change caster to player and let him cast
                if (!GetPlayer().IsOnVehicle(caster) || spellInfo.CheckVehicle(GetPlayer()) != SpellCastResult.SpellCastOk)
                {
                    return;
                }

                caster = GetPlayer();
            }

            // check known spell or raid marker spell (which not requires player to know it)
            if (caster.IsTypeId(TypeId.Player) && !caster.ToPlayer().HasActiveSpell(spellInfo.Id) && !spellInfo.HasEffect(SpellEffectName.ChangeRaidMarker) && !spellInfo.HasAttribute(SpellAttr8.RaidMarker))
            {
                return;
            }

            // Check possible spell cast overrides
            spellInfo = caster.GetCastSpellInfo(spellInfo);

            // Client is resending autoshot cast opcode when other spell is casted during shoot rotation
            // Skip it to prevent "interrupt" message
            if (spellInfo.IsAutoRepeatRangedSpell() && GetPlayer().GetCurrentSpell(CurrentSpellTypes.AutoRepeat) != null &&
                GetPlayer().GetCurrentSpell(CurrentSpellTypes.AutoRepeat).m_spellInfo == spellInfo)
            {
                return;
            }

            // can't use our own spells when we're in possession of another unit,
            if (GetPlayer().isPossessing())
            {
                return;
            }

            // client provided targets
            SpellCastTargets targets = new SpellCastTargets(caster, cast.Cast);

            // auto-selection buff level base at target level (in spellInfo)
            if (targets.GetUnitTarget() != null)
            {
                SpellInfo actualSpellInfo = spellInfo.GetAuraRankForLevel(targets.GetUnitTarget().GetLevelForTarget(caster));

                // if rank not found then function return NULL but in explicit cast case original spell can be casted and later failed with appropriate error message
                if (actualSpellInfo != null)
                {
                    spellInfo = actualSpellInfo;
                }
            }

            if (cast.Cast.MoveUpdate.HasValue)
            {
                HandleMovementOpcode(ClientOpcodes.MoveStop, cast.Cast.MoveUpdate.Value);
            }

            Spell spell = new Spell(caster, spellInfo, TriggerCastFlags.None, ObjectGuid.Empty, false);

            SpellPrepare spellPrepare = new SpellPrepare();

            spellPrepare.ClientCastID = cast.Cast.CastID;
            spellPrepare.ServerCastID = spell.m_castId;
            SendPacket(spellPrepare);

            spell.m_fromClient = true;
            spell.m_misc.Data0 = cast.Cast.Misc[0];
            spell.m_misc.Data1 = cast.Cast.Misc[1];
            spell.prepare(targets);
        }
        void HandleQuestgiverCompleteQuest(QuestGiverCompleteQuest packet)
        {
            bool autoCompleteMode = packet.FromScript; // 0 - standart complete quest mode with npc, 1 - auto-complete mode

            Quest quest = Global.ObjectMgr.GetQuestTemplate(packet.QuestID);

            if (quest == null)
            {
                return;
            }

            if (autoCompleteMode && !quest.HasFlag(QuestFlags.AutoComplete))
            {
                return;
            }

            WorldObject obj;

            if (autoCompleteMode)
            {
                obj = GetPlayer();
            }
            else
            {
                obj = Global.ObjAccessor.GetObjectByTypeMask(GetPlayer(), packet.QuestGiverGUID, TypeMask.Unit | TypeMask.GameObject);
            }

            if (!obj)
            {
                return;
            }

            if (!autoCompleteMode)
            {
                if (!obj.HasInvolvedQuest(packet.QuestID))
                {
                    return;
                }

                // some kind of WPE protection
                if (!GetPlayer().CanInteractWithQuestGiver(obj))
                {
                    return;
                }
            }
            else
            {
                // Do not allow completing quests on other players.
                if (packet.QuestGiverGUID != GetPlayer().GetGUID())
                {
                    return;
                }
            }

            if (!GetPlayer().CanSeeStartQuest(quest) && GetPlayer().GetQuestStatus(packet.QuestID) == QuestStatus.None)
            {
                Log.outError(LogFilter.Network, "Possible hacking attempt: Player {0} ({1}) tried to complete quest [entry: {2}] without being in possession of the quest!",
                             GetPlayer().GetName(), GetPlayer().GetGUID().ToString(), packet.QuestID);
                return;
            }
            Battleground bg = GetPlayer().GetBattleground();

            if (bg)
            {
                bg.HandleQuestComplete(packet.QuestID, GetPlayer());
            }

            if (GetPlayer().GetQuestStatus(packet.QuestID) != QuestStatus.Complete)
            {
                if (quest.IsRepeatable())
                {
                    GetPlayer().PlayerTalkClass.SendQuestGiverRequestItems(quest, packet.QuestGiverGUID, GetPlayer().CanCompleteRepeatableQuest(quest), false);
                }
                else
                {
                    GetPlayer().PlayerTalkClass.SendQuestGiverRequestItems(quest, packet.QuestGiverGUID, GetPlayer().CanRewardQuest(quest, false), false);
                }
            }
            else
            {
                if (quest.HasSpecialFlag(QuestSpecialFlags.Deliver))                  // some items required
                {
                    GetPlayer().PlayerTalkClass.SendQuestGiverRequestItems(quest, packet.QuestGiverGUID, GetPlayer().CanRewardQuest(quest, false), false);
                }
                else                                            // no items required
                {
                    GetPlayer().PlayerTalkClass.SendQuestGiverOfferReward(quest, packet.QuestGiverGUID, true);
                }
            }
        }
        public uint SendChat(Creature source, byte textGroup, WorldObject whisperTarget = null, ChatMsg msgType = ChatMsg.Addon, Language language = Language.Addon,
                             CreatureTextRange range = CreatureTextRange.Normal, uint sound = 0, SoundKitPlayType playType = SoundKitPlayType.Normal, Team team = Team.Other, bool gmOnly = false, Player srcPlr = null)
        {
            if (source == null)
            {
                return(0);
            }

            var sList = mTextMap.LookupByKey(source.GetEntry());

            if (sList == null)
            {
                Log.outError(LogFilter.Sql, "GossipManager: Could not find Text for Creature({0}) Entry {1} in 'creature_text' table. Ignoring.", source.GetName(), source.GetEntry());
                return(0);
            }

            var textGroupContainer = sList.LookupByKey(textGroup);

            if (textGroupContainer.Empty())
            {
                Log.outError(LogFilter.ChatSystem, "GossipManager: Could not find TextGroup {0} for Creature({1}) GuidLow {2} Entry {3}. Ignoring.", textGroup, source.GetName(), source.GetGUID().ToString(), source.GetEntry());
                return(0);
            }

            List <CreatureTextEntry> tempGroup = new();
            var repeatGroup = source.GetTextRepeatGroup(textGroup);

            foreach (var entry in textGroupContainer)
            {
                if (!repeatGroup.Contains(entry.id))
                {
                    tempGroup.Add(entry);
                }
            }

            if (tempGroup.Empty())
            {
                source.ClearTextRepeatGroup(textGroup);
                tempGroup = textGroupContainer;
            }

            var textEntry = tempGroup.SelectRandomElementByWeight(t => t.probability);

            ChatMsg          finalType     = (msgType == ChatMsg.Addon) ? textEntry.type : msgType;
            Language         finalLang     = (language == Language.Addon) ? textEntry.lang : language;
            uint             finalSound    = textEntry.sound;
            SoundKitPlayType finalPlayType = textEntry.SoundPlayType;

            if (sound != 0)
            {
                finalSound    = sound;
                finalPlayType = playType;
            }
            else
            {
                BroadcastTextRecord bct = CliDB.BroadcastTextStorage.LookupByKey(textEntry.BroadcastTextId);
                if (bct != null)
                {
                    uint broadcastTextSoundId = bct.SoundKitID[source.GetGender() == Gender.Female ? 1 : 0];
                    if (broadcastTextSoundId != 0)
                    {
                        finalSound = broadcastTextSoundId;
                    }
                }
            }

            if (range == CreatureTextRange.Normal)
            {
                range = textEntry.TextRange;
            }

            if (finalSound != 0)
            {
                SendSound(source, finalSound, finalType, whisperTarget, range, team, gmOnly, textEntry.BroadcastTextId, finalPlayType);
            }

            Unit finalSource = source;

            if (srcPlr)
            {
                finalSource = srcPlr;
            }

            if (textEntry.emote != 0)
            {
                SendEmote(finalSource, textEntry.emote);
            }

            if (srcPlr)
            {
                PlayerTextBuilder builder = new(source, finalSource, finalSource.GetGender(), finalType, textEntry.groupId, textEntry.id, finalLang, whisperTarget);
                SendChatPacket(finalSource, builder, finalType, whisperTarget, range, team, gmOnly);
            }
            else
            {
                CreatureTextBuilder builder = new(finalSource, finalSource.GetGender(), finalType, textEntry.groupId, textEntry.id, finalLang, whisperTarget);
                SendChatPacket(finalSource, builder, finalType, whisperTarget, range, team, gmOnly);
            }

            source.SetTextRepeatId(textGroup, textEntry.id);
            return(textEntry.duration);
        }
Exemple #6
0
        void HandleMoveWorldportAck()
        {
            // ignore unexpected far teleports
            if (!GetPlayer().IsBeingTeleportedFar())
            {
                return;
            }

            bool seamlessTeleport = GetPlayer().IsBeingTeleportedSeamlessly();

            GetPlayer().SetSemaphoreTeleportFar(false);

            // get the teleport destination
            WorldLocation loc = GetPlayer().GetTeleportDest();

            // possible errors in the coordinate validity check
            if (!GridDefines.IsValidMapCoord(loc))
            {
                LogoutPlayer(false);
                return;
            }

            // get the destination map entry, not the current one, this will fix homebind and reset greeting
            MapRecord        mapEntry  = CliDB.MapStorage.LookupByKey(loc.GetMapId());
            InstanceTemplate mInstance = Global.ObjectMgr.GetInstanceTemplate(loc.GetMapId());

            // reset instance validity, except if going to an instance inside an instance
            if (!GetPlayer().m_InstanceValid&& mInstance == null)
            {
                GetPlayer().m_InstanceValid = true;
            }

            Map oldMap = GetPlayer().GetMap();
            Map newMap = Global.MapMgr.CreateMap(loc.GetMapId(), GetPlayer());

            if (GetPlayer().IsInWorld)
            {
                Log.outError(LogFilter.Network, "Player (Name {0}) is still in world when teleported from map {1} to new map {2}", GetPlayer().GetName(), oldMap.GetId(), loc.GetMapId());
                oldMap.RemovePlayerFromMap(GetPlayer(), false);
            }

            // relocate the player to the teleport destination
            // the CannotEnter checks are done in TeleporTo but conditions may change
            // while the player is in transit, for example the map may get full
            if (newMap == null || newMap.CannotEnter(GetPlayer()) != 0)
            {
                Log.outError(LogFilter.Network, "Map {0} could not be created for {1} ({2}), porting player to homebind", loc.GetMapId(), newMap ? newMap.GetMapName() : "Unknown", GetPlayer().GetGUID().ToString());
                GetPlayer().TeleportTo(GetPlayer().GetHomebind());
                return;
            }

            float z = loc.GetPositionZ();

            if (GetPlayer().HasUnitMovementFlag(MovementFlag.Hover))
            {
                z += GetPlayer().m_unitData.HoverHeight;
            }

            GetPlayer().Relocate(loc.GetPositionX(), loc.GetPositionY(), z, loc.GetOrientation());
            GetPlayer().SetFallInformation(0, GetPlayer().GetPositionZ());

            GetPlayer().ResetMap();
            GetPlayer().SetMap(newMap);

            ResumeToken resumeToken = new();

            resumeToken.SequenceIndex = _player.m_movementCounter;
            resumeToken.Reason        = seamlessTeleport ? 2 : 1u;
            SendPacket(resumeToken);

            if (!seamlessTeleport)
            {
                GetPlayer().SendInitialPacketsBeforeAddToMap();
            }

            if (!GetPlayer().GetMap().AddPlayerToMap(GetPlayer(), !seamlessTeleport))
            {
                Log.outError(LogFilter.Network, "WORLD: failed to teleport player {0} ({1}) to map {2} ({3}) because of unknown reason!",
                             GetPlayer().GetName(), GetPlayer().GetGUID().ToString(), loc.GetMapId(), newMap ? newMap.GetMapName() : "Unknown");
                GetPlayer().ResetMap();
                GetPlayer().SetMap(oldMap);
                GetPlayer().TeleportTo(GetPlayer().GetHomebind());
                return;
            }

            // Battleground state prepare (in case join to BG), at relogin/tele player not invited
            // only add to bg group and object, if the player was invited (else he entered through command)
            if (GetPlayer().InBattleground())
            {
                // cleanup setting if outdated
                if (!mapEntry.IsBattlegroundOrArena())
                {
                    // We're not in BG
                    GetPlayer().SetBattlegroundId(0, BattlegroundTypeId.None);
                    // reset destination bg team
                    GetPlayer().SetBGTeam(0);
                }
                // join to bg case
                else
                {
                    Battleground bg = GetPlayer().GetBattleground();
                    if (bg)
                    {
                        if (GetPlayer().IsInvitedForBattlegroundInstance(GetPlayer().GetBattlegroundId()))
                        {
                            bg.AddPlayer(GetPlayer());
                        }
                    }
                }
            }

            if (!seamlessTeleport)
            {
                GetPlayer().SendInitialPacketsAfterAddToMap();
            }
            else
            {
                GetPlayer().UpdateVisibilityForPlayer();
                Garrison garrison = GetPlayer().GetGarrison();
                if (garrison != null)
                {
                    garrison.SendRemoteInfo();
                }
            }

            // flight fast teleport case
            if (GetPlayer().GetMotionMaster().GetCurrentMovementGeneratorType() == MovementGeneratorType.Flight)
            {
                if (!GetPlayer().InBattleground())
                {
                    if (!seamlessTeleport)
                    {
                        // short preparations to continue flight
                        IMovementGenerator movementGenerator = GetPlayer().GetMotionMaster().Top();
                        movementGenerator.Initialize(GetPlayer());
                    }
                    return;
                }

                // Battlegroundstate prepare, stop flight
                GetPlayer().GetMotionMaster().MovementExpired();
                GetPlayer().CleanupAfterTaxiFlight();
            }

            // resurrect character at enter into instance where his corpse exist after add to map
            if (mapEntry.IsDungeon() && !GetPlayer().IsAlive())
            {
                if (GetPlayer().GetCorpseLocation().GetMapId() == mapEntry.Id)
                {
                    GetPlayer().ResurrectPlayer(0.5f, false);
                    GetPlayer().SpawnCorpseBones();
                }
            }

            bool allowMount = !mapEntry.IsDungeon() || mapEntry.IsBattlegroundOrArena();

            if (mInstance != null)
            {
                // check if this instance has a reset time and send it to player if so
                Difficulty          diff    = newMap.GetDifficultyID();
                MapDifficultyRecord mapDiff = Global.DB2Mgr.GetMapDifficultyData(mapEntry.Id, diff);
                if (mapDiff != null)
                {
                    if (mapDiff.GetRaidDuration() != 0)
                    {
                        long timeReset = Global.InstanceSaveMgr.GetResetTimeFor(mapEntry.Id, diff);
                        if (timeReset != 0)
                        {
                            uint timeleft = (uint)(timeReset - Time.UnixTime);
                            GetPlayer().SendInstanceResetWarning(mapEntry.Id, diff, timeleft, true);
                        }
                    }
                }

                // check if instance is valid
                if (!GetPlayer().CheckInstanceValidity(false))
                {
                    GetPlayer().m_InstanceValid = false;
                }

                // instance mounting is handled in InstanceTemplate
                allowMount = mInstance.AllowMount;
            }

            // mount allow check
            if (!allowMount)
            {
                GetPlayer().RemoveAurasByType(AuraType.Mounted);
            }

            // update zone immediately, otherwise leave channel will cause crash in mtmap
            uint newzone, newarea;

            GetPlayer().GetZoneAndAreaId(out newzone, out newarea);
            GetPlayer().UpdateZone(newzone, newarea);

            // honorless target
            if (GetPlayer().pvpInfo.IsHostile)
            {
                GetPlayer().CastSpell(GetPlayer(), 2479, true);
            }

            // in friendly area
            else if (GetPlayer().IsPvP() && !GetPlayer().HasPlayerFlag(PlayerFlags.InPVP))
            {
                GetPlayer().UpdatePvP(false, false);
            }

            // resummon pet
            GetPlayer().ResummonPetTemporaryUnSummonedIfAny();

            //lets process all delayed operations on successful teleport
            GetPlayer().ProcessDelayedOperations();
        }
Exemple #7
0
        void HandleMovementOpcode(ClientOpcodes opcode, MovementInfo movementInfo)
        {
            Unit   mover    = GetPlayer().m_unitMovedByMe;
            Player plrMover = mover.ToPlayer();

            if (plrMover && plrMover.IsBeingTeleported())
            {
                return;
            }

            GetPlayer().ValidateMovementInfo(movementInfo);

            if (movementInfo.Guid != mover.GetGUID())
            {
                Log.outError(LogFilter.Network, "HandleMovementOpcodes: guid error");
                return;
            }
            if (!movementInfo.Pos.IsPositionValid())
            {
                Log.outError(LogFilter.Network, "HandleMovementOpcodes: Invalid Position");
                return;
            }

            // stop some emotes at player move
            if (plrMover && (plrMover.GetEmoteState() != 0))
            {
                plrMover.SetEmoteState(Emote.OneshotNone);
            }

            //handle special cases
            if (!movementInfo.transport.guid.IsEmpty())
            {
                // We were teleported, skip packets that were broadcast before teleport
                if (movementInfo.Pos.GetExactDist2d(mover) > MapConst.SizeofGrids)
                {
                    return;
                }

                if (Math.Abs(movementInfo.transport.pos.GetPositionX()) > 75f || Math.Abs(movementInfo.transport.pos.GetPositionY()) > 75f || Math.Abs(movementInfo.transport.pos.GetPositionZ()) > 75f)
                {
                    return;
                }

                if (!GridDefines.IsValidMapCoord(movementInfo.Pos.posX + movementInfo.transport.pos.posX, movementInfo.Pos.posY + movementInfo.transport.pos.posY,
                                                 movementInfo.Pos.posZ + movementInfo.transport.pos.posZ, movementInfo.Pos.Orientation + movementInfo.transport.pos.Orientation))
                {
                    return;
                }

                if (plrMover)
                {
                    if (!plrMover.GetTransport())
                    {
                        Transport transport = plrMover.GetMap().GetTransport(movementInfo.transport.guid);
                        if (transport)
                        {
                            transport.AddPassenger(plrMover);
                        }
                    }
                    else if (plrMover.GetTransport().GetGUID() != movementInfo.transport.guid)
                    {
                        plrMover.GetTransport().RemovePassenger(plrMover);
                        Transport transport = plrMover.GetMap().GetTransport(movementInfo.transport.guid);
                        if (transport)
                        {
                            transport.AddPassenger(plrMover);
                        }
                        else
                        {
                            movementInfo.ResetTransport();
                        }
                    }
                }

                if (!mover.GetTransport() && !mover.GetVehicle())
                {
                    GameObject go = mover.GetMap().GetGameObject(movementInfo.transport.guid);
                    if (!go || go.GetGoType() != GameObjectTypes.Transport)
                    {
                        movementInfo.transport.Reset();
                    }
                }
            }
            else if (plrMover && plrMover.GetTransport())                // if we were on a transport, leave
            {
                plrMover.GetTransport().RemovePassenger(plrMover);
            }

            // fall damage generation (ignore in flight case that can be triggered also at lags in moment teleportation to another map).
            if (opcode == ClientOpcodes.MoveFallLand && plrMover && !plrMover.IsInFlight())
            {
                plrMover.HandleFall(movementInfo);
            }

            // interrupt parachutes upon falling or landing in water
            if (opcode == ClientOpcodes.MoveFallLand || opcode == ClientOpcodes.MoveStartSwim)
            {
                mover.RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags.Landing); // Parachutes
            }
            uint mstime = GameTime.GetGameTimeMS();

            if (m_clientTimeDelay == 0)
            {
                m_clientTimeDelay = mstime - movementInfo.Time;
            }

            movementInfo.Time = movementInfo.Time + m_clientTimeDelay;

            movementInfo.Guid    = mover.GetGUID();
            mover.m_movementInfo = movementInfo;

            // Some vehicles allow the passenger to turn by himself
            Vehicle vehicle = mover.GetVehicle();

            if (vehicle)
            {
                VehicleSeatRecord seat = vehicle.GetSeatForPassenger(mover);
                if (seat != null)
                {
                    if (seat.HasSeatFlag(VehicleSeatFlags.AllowTurning))
                    {
                        if (movementInfo.Pos.GetOrientation() != mover.GetOrientation())
                        {
                            mover.SetOrientation(movementInfo.Pos.GetOrientation());
                            mover.RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags.Turning);
                        }
                    }
                }
                return;
            }

            mover.UpdatePosition(movementInfo.Pos);

            MoveUpdate moveUpdate = new();

            moveUpdate.Status = mover.m_movementInfo;
            mover.SendMessageToSet(moveUpdate, GetPlayer());

            if (plrMover)                                            // nothing is charmed, or player charmed
            {
                if (plrMover.IsSitState() && movementInfo.HasMovementFlag(MovementFlag.MaskMoving | MovementFlag.MaskTurning))
                {
                    plrMover.SetStandState(UnitStandStateType.Stand);
                }

                plrMover.UpdateFallInformationIfNeed(movementInfo, opcode);

                if (movementInfo.Pos.posZ < plrMover.GetMap().GetMinHeight(plrMover.GetPhaseShift(), movementInfo.Pos.GetPositionX(), movementInfo.Pos.GetPositionY()))
                {
                    if (!(plrMover.GetBattleground() && plrMover.GetBattleground().HandlePlayerUnderMap(GetPlayer())))
                    {
                        // NOTE: this is actually called many times while falling
                        // even after the player has been teleported away
                        // @todo discard movement packets after the player is rooted
                        if (plrMover.IsAlive())
                        {
                            plrMover.AddPlayerFlag(PlayerFlags.IsOutOfBounds);
                            plrMover.EnvironmentalDamage(EnviromentalDamage.FallToVoid, (uint)GetPlayer().GetMaxHealth());
                            // player can be alive if GM/etc
                            // change the death state to CORPSE to prevent the death timer from
                            // starting in the next player update
                            if (plrMover.IsAlive())
                            {
                                plrMover.KillPlayer();
                            }
                        }
                    }
                }
                else
                {
                    plrMover.RemovePlayerFlag(PlayerFlags.IsOutOfBounds);
                }

                if (opcode == ClientOpcodes.MoveJump)
                {
                    plrMover.RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags.Jump, 605); // Mind Control
                    plrMover.ProcSkillsAndAuras(null, ProcFlags.Jump, ProcFlags.None, ProcFlagsSpellType.MaskAll, ProcFlagsSpellPhase.None, ProcFlagsHit.None, null, null, null);
                }
            }
        }
Exemple #8
0
 BattlenetRpcErrorCode HandleGetAchievementsFile(GetAchievementsFileRequest request, GetAchievementsFileResponse response)
 {
     Log.outError(LogFilter.ServiceProtobuf, "{0} Client tried to call not implemented method GameUtilitiesService.GetAchievementsFile: {1}",
                  GetCallerInfo(), request.ToString());
     return(BattlenetRpcErrorCode.RpcNotImplemented);
 }
Exemple #9
0
        public override void CallServerMethod(uint token, uint methodId, CodedInputStream stream)
        {
            switch (methodId)
            {
            case 1:
            {
                ClientRequest request = new ClientRequest();
                request.MergeFrom(stream);


                ClientResponse        response = new ClientResponse();
                BattlenetRpcErrorCode status   = HandleProcessClientRequest(request, response);
                Log.outDebug(LogFilter.ServiceProtobuf, "{0} Client called server method GameUtilitiesService.ProcessClientRequest(bgs.protocol.game_utilities.v1.ClientRequest: {1}) returned bgs.protocol.game_utilities.v1.ClientResponse: {2} status: {3}.",
                             GetCallerInfo(), request.ToString(), response.ToString(), status);
                if (status == 0)
                {
                    SendResponse(1, token, response);
                }
                else
                {
                    SendResponse(1, token, status);
                }
                break;
            }

            case 2:
            {
                PresenceChannelCreatedRequest request = new PresenceChannelCreatedRequest();
                request.MergeFrom(stream);


                Bgs.Protocol.NoData   response = new Bgs.Protocol.NoData();
                BattlenetRpcErrorCode status   = HandlePresenceChannelCreated(request, response);
                Log.outDebug(LogFilter.ServiceProtobuf, "{0} Client called server method GameUtilitiesService.PresenceChannelCreated(bgs.protocol.game_utilities.v1.PresenceChannelCreatedRequest: {1}) returned bgs.protocol.NoData: {2} status: {3}.",
                             GetCallerInfo(), request.ToString(), response.ToString(), status);
                if (status == 0)
                {
                    SendResponse(2, token, response);
                }
                else
                {
                    SendResponse(2, token, status);
                }
                break;
            }

            case 3:
            {
                GetPlayerVariablesRequest request = new GetPlayerVariablesRequest();
                request.MergeFrom(stream);


                GetPlayerVariablesResponse response = new GetPlayerVariablesResponse();
                BattlenetRpcErrorCode      status   = HandleGetPlayerVariables(request, response);
                Log.outDebug(LogFilter.ServiceProtobuf, "{0} Client called server method GameUtilitiesService.GetPlayerVariables(bgs.protocol.game_utilities.v1.GetPlayerVariablesRequest: {1}) returned bgs.protocol.game_utilities.v1.GetPlayerVariablesResponse: {2} status: {3}.",
                             GetCallerInfo(), request.ToString(), response.ToString(), status);
                if (status == 0)
                {
                    SendResponse(3, token, response);
                }
                else
                {
                    SendResponse(3, token, status);
                }
                break;
            }

            case 6:
            {
                ServerRequest request = new ServerRequest();
                request.MergeFrom(stream);


                ServerResponse        response = new ServerResponse();
                BattlenetRpcErrorCode status   = HandleProcessServerRequest(request, response);
                Log.outDebug(LogFilter.ServiceProtobuf, "{0} Client called server method GameUtilitiesService.ProcessServerRequest(bgs.protocol.game_utilities.v1.ServerRequest: {1}) returned bgs.protocol.game_utilities.v1.ServerResponse: {2} status: {3}.",
                             GetCallerInfo(), request.ToString(), response.ToString(), status);
                if (status == 0)
                {
                    SendResponse(6, token, response);
                }
                else
                {
                    SendResponse(6, token, status);
                }
                break;
            }

            case 7:
            {
                GameAccountOnlineNotification request = new GameAccountOnlineNotification();
                request.MergeFrom(stream);


                BattlenetRpcErrorCode status = HandleOnGameAccountOnline(request);
                Log.outDebug(LogFilter.ServiceProtobuf, "{0} Client called server method GameUtilitiesService.OnGameAccountOnline(bgs.protocol.game_utilities.v1.GameAccountOnlineNotification: {1}) status: {2}.",
                             GetCallerInfo(), request.ToString(), status);
                if (status != 0)
                {
                    SendResponse(7, token, status);
                }
                break;
            }

            case 8:
            {
                GameAccountOfflineNotification request = new GameAccountOfflineNotification();
                request.MergeFrom(stream);


                BattlenetRpcErrorCode status = HandleOnGameAccountOffline(request);
                Log.outDebug(LogFilter.ServiceProtobuf, "{0} Client called server method GameUtilitiesService.OnGameAccountOffline(bgs.protocol.game_utilities.v1.GameAccountOfflineNotification: {1}) status: {2}.",
                             GetCallerInfo(), request.ToString(), status);
                if (status != 0)
                {
                    SendResponse(8, token, status);
                }
                break;
            }

            case 9:
            {
                GetAchievementsFileRequest request = new GetAchievementsFileRequest();
                request.MergeFrom(stream);


                GetAchievementsFileResponse response = new GetAchievementsFileResponse();
                BattlenetRpcErrorCode       status   = HandleGetAchievementsFile(request, response);
                Log.outDebug(LogFilter.ServiceProtobuf, "{0} Client called server method GameUtilitiesService.GetAchievementsFile(bgs.protocol.game_utilities.v1.GetAchievementsFileRequest: {1}) returned bgs.protocol.game_utilities.v1.GetAchievementsFileResponse: {2} status: {3}.",
                             GetCallerInfo(), request.ToString(), response.ToString(), status);
                if (status == 0)
                {
                    SendResponse(9, token, response);
                }
                else
                {
                    SendResponse(9, token, status);
                }
                break;
            }

            case 10:
            {
                GetAllValuesForAttributeRequest request = new GetAllValuesForAttributeRequest();
                request.MergeFrom(stream);


                GetAllValuesForAttributeResponse response = new GetAllValuesForAttributeResponse();
                BattlenetRpcErrorCode            status   = HandleGetAllValuesForAttribute(request, response);
                Log.outDebug(LogFilter.ServiceProtobuf, "{0} Client called server method GameUtilitiesService.GetAllValuesForAttribute(bgs.protocol.game_utilities.v1.GetAllValuesForAttributeRequest: {1}) returned bgs.protocol.game_utilities.v1.GetAllValuesForAttributeResponse: {2} status: {3}.",
                             GetCallerInfo(), request.ToString(), response.ToString(), status);
                if (status == 0)
                {
                    SendResponse(10, token, response);
                }
                else
                {
                    SendResponse(10, token, status);
                }
                break;
            }

            default:
                Log.outError(LogFilter.ServiceProtobuf, "Bad method id {0}.", methodId);
                SendResponse(methodId, token, BattlenetRpcErrorCode.RpcInvalidMethod);
                break;
            }
        }
Exemple #10
0
 BattlenetRpcErrorCode HandlePresenceChannelCreated(PresenceChannelCreatedRequest request, Bgs.Protocol.NoData response)
 {
     Log.outError(LogFilter.ServiceProtobuf, "{0} Client tried to call not implemented method GameUtilitiesService.PresenceChannelCreated: {1}",
                  GetCallerInfo(), request.ToString());
     return(BattlenetRpcErrorCode.RpcNotImplemented);
 }
Exemple #11
0
 BattlenetRpcErrorCode HandleOnGameAccountOffline(GameAccountOfflineNotification request)
 {
     Log.outError(LogFilter.ServiceProtobuf, "{0} Client tried to call not implemented method GameUtilitiesService.OnGameAccountOffline: {1}",
                  GetCallerInfo(), request.ToString());
     return(BattlenetRpcErrorCode.RpcNotImplemented);
 }
        void HandleTurnInPetition(TurnInPetition packet)
        {
            // Check if player really has the required petition charter
            Item item = GetPlayer().GetItemByGuid(packet.Item);

            if (!item)
            {
                return;
            }

            // Get petition data from db
            ObjectGuid ownerguid;
            string     name;

            PreparedStatement stmt = DB.Characters.GetPreparedStatement(CharStatements.SEL_PETITION);

            stmt.AddValue(0, packet.Item.GetCounter());
            SQLResult result = DB.Characters.Query(stmt);

            if (!result.IsEmpty())
            {
                ownerguid = ObjectGuid.Create(HighGuid.Player, result.Read <ulong>(0));
                name      = result.Read <string>(1);
            }
            else
            {
                Log.outError(LogFilter.Network, "Player {0} ({1}) tried to turn in petition ({2}) that is not present in the database", GetPlayer().GetName(), GetPlayer().GetGUID().ToString(), packet.Item.ToString());
                return;
            }

            // Only the petition owner can turn in the petition
            if (GetPlayer().GetGUID() != ownerguid)
            {
                return;
            }

            TurnInPetitionResult resultPacket = new TurnInPetitionResult();

            // Check if player is already in a guild
            if (GetPlayer().GetGuildId() != 0)
            {
                resultPacket.Result = PetitionTurns.AlreadyInGuild;
                GetPlayer().SendPacket(resultPacket);
                return;
            }

            // Check if guild name is already taken
            if (Global.GuildMgr.GetGuildByName(name))
            {
                Guild.SendCommandResult(this, GuildCommandType.CreateGuild, GuildCommandError.NameExists_S, name);
                return;
            }

            // Get petition signatures from db
            stmt = DB.Characters.GetPreparedStatement(CharStatements.SEL_PETITION_SIGNATURE);
            stmt.AddValue(0, packet.Item.GetCounter());
            result = DB.Characters.Query(stmt);

            List <ObjectGuid> guids = new List <ObjectGuid>();

            if (!result.IsEmpty())
            {
                do
                {
                    guids.Add(ObjectGuid.Create(HighGuid.Player, result.Read <ulong>(0)));
                }while (result.NextRow());
            }

            uint requiredSignatures = WorldConfig.GetUIntValue(WorldCfg.MinPetitionSigns);

            // Notify player if signatures are missing
            if (guids.Count < requiredSignatures)
            {
                resultPacket.Result = PetitionTurns.NeedMoreSignatures;
                SendPacket(resultPacket);
                return;
            }
            // Proceed with guild/arena team creation

            // Delete charter item
            GetPlayer().DestroyItem(item.GetBagSlot(), item.GetSlot(), true);

            // Create guild
            Guild guild = new Guild();

            if (!guild.Create(GetPlayer(), name))
            {
                return;
            }

            // Register guild and add guild master
            Global.GuildMgr.AddGuild(guild);

            Guild.SendCommandResult(this, GuildCommandType.CreateGuild, GuildCommandError.Success, name);

            SQLTransaction trans = new SQLTransaction();

            // Add members from signatures
            foreach (var guid in guids)
            {
                guild.AddMember(trans, guid);
            }

            stmt = DB.Characters.GetPreparedStatement(CharStatements.DEL_PETITION_BY_GUID);
            stmt.AddValue(0, packet.Item.GetCounter());
            trans.Append(stmt);

            stmt = DB.Characters.GetPreparedStatement(CharStatements.DEL_PETITION_SIGNATURE_BY_GUID);
            stmt.AddValue(0, packet.Item.GetCounter());
            trans.Append(stmt);

            DB.Characters.CommitTransaction(trans);

            // created
            Log.outDebug(LogFilter.Network, "Player {0} ({1}) turning in petition {2}", GetPlayer().GetName(), GetPlayer().GetGUID().ToString(), packet.Item.ToString());

            resultPacket.Result = PetitionTurns.Ok;
            SendPacket(resultPacket);
        }
        void HandleSignPetition(SignPetition packet)
        {
            PreparedStatement stmt = DB.Characters.GetPreparedStatement(CharStatements.SEL_PETITION_SIGNATURES);

            stmt.AddValue(0, packet.PetitionGUID.GetCounter());
            stmt.AddValue(1, packet.PetitionGUID.GetCounter());
            SQLResult result = DB.Characters.Query(stmt);

            if (result.IsEmpty())
            {
                Log.outError(LogFilter.Network, "Petition {0} is not found for player {1} {2}", packet.PetitionGUID.ToString(), GetPlayer().GetGUID().ToString(), GetPlayer().GetName());
                return;
            }

            ObjectGuid ownerGuid = ObjectGuid.Create(HighGuid.Player, result.Read <ulong>(0));

            //ulong signs = result.Read<ulong>(1);

            if (ownerGuid == GetPlayer().GetGUID())
            {
                return;
            }

            // not let enemies sign guild charter
            if (!WorldConfig.GetBoolValue(WorldCfg.AllowTwoSideInteractionGuild) && GetPlayer().GetTeam() != ObjectManager.GetPlayerTeamByGUID(ownerGuid))
            {
                Guild.SendCommandResult(this, GuildCommandType.CreateGuild, GuildCommandError.NotAllied);
                return;
            }

            if (GetPlayer().GetGuildId() != 0)
            {
                Guild.SendCommandResult(this, GuildCommandType.InvitePlayer, GuildCommandError.AlreadyInGuild_S, GetPlayer().GetName());
                return;
            }
            if (GetPlayer().GetGuildIdInvited() != 0)
            {
                Guild.SendCommandResult(this, GuildCommandType.InvitePlayer, GuildCommandError.AlreadyInvitedToGuild_S, GetPlayer().GetName());
                return;
            }

            // Client doesn't allow to sign petition two times by one character, but not check sign by another character from same account
            // not allow sign another player from already sign player account
            stmt = DB.Characters.GetPreparedStatement(CharStatements.SEL_PETITION_SIG_BY_ACCOUNT);
            stmt.AddValue(0, GetAccountId());
            stmt.AddValue(1, packet.PetitionGUID.GetCounter());
            result = DB.Characters.Query(stmt);

            PetitionSignResults signResult = new PetitionSignResults();

            signResult.Player = GetPlayer().GetGUID();
            signResult.Item   = packet.PetitionGUID;

            if (!result.IsEmpty())
            {
                signResult.Error = PetitionSigns.AlreadySigned;

                // close at signer side
                SendPacket(signResult);
                return;
            }

            stmt = DB.Characters.GetPreparedStatement(CharStatements.INS_PETITION_SIGNATURE);
            stmt.AddValue(0, ownerGuid.GetCounter());
            stmt.AddValue(1, packet.PetitionGUID.GetCounter());
            stmt.AddValue(2, GetPlayer().GetGUID().GetCounter());
            stmt.AddValue(3, GetAccountId());
            DB.Characters.Execute(stmt);

            Log.outDebug(LogFilter.Network, "PETITION SIGN: {0} by player: {1} ({2} Account: {3})", packet.PetitionGUID.ToString(), GetPlayer().GetName(), GetPlayer().GetGUID().ToString(), GetAccountId());

            signResult.Error = PetitionSigns.Ok;

            // close at signer side
            SendPacket(signResult);

            // update for owner if online
            Player owner = Global.ObjAccessor.FindPlayer(ownerGuid);

            if (owner)
            {
                owner.SendPacket(signResult);
            }
        }
Exemple #14
0
        void HandlePetCastSpell(PetCastSpell petCastSpell)
        {
            Unit caster = Global.ObjAccessor.GetUnit(GetPlayer(), petCastSpell.PetGUID);

            if (!caster)
            {
                Log.outError(LogFilter.Network, "WorldSession.HandlePetCastSpell: Caster {0} not found.", petCastSpell.PetGUID.ToString());
                return;
            }

            SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(petCastSpell.Cast.SpellID, caster.GetMap().GetDifficultyID());

            if (spellInfo == null)
            {
                Log.outError(LogFilter.Network, "WorldSession.HandlePetCastSpell: unknown spell id {0} tried to cast by {1}", petCastSpell.Cast.SpellID, petCastSpell.PetGUID.ToString());
                return;
            }

            // This opcode is also sent from charmed and possessed units (players and creatures)
            if (caster != GetPlayer().GetGuardianPet() && caster != GetPlayer().GetCharmed())
            {
                Log.outError(LogFilter.Network, "WorldSession.HandlePetCastSpell: {0} isn't pet of player {1} ({2}).", petCastSpell.PetGUID.ToString(), GetPlayer().GetName(), GetPlayer().GetGUID().ToString());
                return;
            }

            SpellCastTargets targets = new(caster, petCastSpell.Cast);

            TriggerCastFlags triggerCastFlags = TriggerCastFlags.None;

            if (spellInfo.IsPassive())
            {
                return;
            }

            // cast only learned spells
            if (!caster.HasSpell(spellInfo.Id))
            {
                bool allow = false;

                // allow casting of spells triggered by clientside periodic trigger auras
                if (caster.HasAuraTypeWithTriggerSpell(AuraType.PeriodicTriggerSpellFromClient, spellInfo.Id))
                {
                    allow            = true;
                    triggerCastFlags = TriggerCastFlags.FullMask;
                }

                if (!allow)
                {
                    return;
                }
            }

            Spell spell = new(caster, spellInfo, triggerCastFlags);

            spell.m_fromClient = true;
            spell.m_misc.Data0 = petCastSpell.Cast.Misc[0];
            spell.m_misc.Data1 = petCastSpell.Cast.Misc[1];
            spell.m_targets    = targets;

            SpellCastResult result = spell.CheckPetCast(null);

            if (result == SpellCastResult.SpellCastOk)
            {
                Creature creature = caster.ToCreature();
                if (creature)
                {
                    Pet pet = creature.ToPet();
                    if (pet)
                    {
                        // 10% chance to play special pet attack talk, else growl
                        // actually this only seems to happen on special spells, fire shield for imp, torment for voidwalker, but it's stupid to check every spell
                        if (pet.GetPetType() == PetType.Summon && (RandomHelper.IRand(0, 100) < 10))
                        {
                            pet.SendPetTalk(PetTalk.SpecialSpell);
                        }
                        else
                        {
                            pet.SendPetAIReaction(petCastSpell.PetGUID);
                        }
                    }
                }

                SpellPrepare spellPrepare = new();
                spellPrepare.ClientCastID = petCastSpell.Cast.CastID;
                spellPrepare.ServerCastID = spell.m_castId;
                SendPacket(spellPrepare);

                spell.Prepare(targets);
            }
            else
            {
                spell.SendPetCastResult(result);

                if (!caster.GetSpellHistory().HasCooldown(spellInfo.Id))
                {
                    caster.GetSpellHistory().ResetCooldown(spellInfo.Id, true);
                }

                spell.Finish(false);
                spell.Dispose();
            }
        }
Exemple #15
0
        void HandleMovementOpcode(ClientOpcodes opcode, MovementInfo movementInfo)
        {
            Unit   mover    = GetPlayer().m_unitMovedByMe;
            Player plrMover = mover.ToPlayer();

            if (plrMover && plrMover.IsBeingTeleported())
            {
                return;
            }

            GetPlayer().ValidateMovementInfo(movementInfo);

            if (movementInfo.Guid != mover.GetGUID())
            {
                Log.outError(LogFilter.Network, "HandleMovementOpcodes: guid error");
                return;
            }
            if (!movementInfo.Pos.IsPositionValid())
            {
                Log.outError(LogFilter.Network, "HandleMovementOpcodes: Invalid Position");
                return;
            }

            // stop some emotes at player move
            if (plrMover && (plrMover.GetUInt32Value(UnitFields.NpcEmotestate) != 0))
            {
                plrMover.SetUInt32Value(UnitFields.NpcEmotestate, (uint)Emote.OneshotNone);
            }

            //handle special cases
            if (!movementInfo.transport.guid.IsEmpty())
            {
                if (movementInfo.transport.pos.GetPositionX() > 50 || movementInfo.transport.pos.GetPositionY() > 50 || movementInfo.transport.pos.GetPositionZ() > 50)
                {
                    return;
                }

                if (!GridDefines.IsValidMapCoord(movementInfo.Pos.posX + movementInfo.transport.pos.posX, movementInfo.Pos.posY + movementInfo.transport.pos.posY,
                                                 movementInfo.Pos.posZ + movementInfo.transport.pos.posZ, movementInfo.Pos.Orientation + movementInfo.transport.pos.Orientation))
                {
                    return;
                }

                if (plrMover)
                {
                    if (!plrMover.GetTransport())
                    {
                        Transport transport = plrMover.GetMap().GetTransport(movementInfo.transport.guid);
                        if (transport)
                        {
                            transport.AddPassenger(plrMover);
                        }
                    }
                    else if (plrMover.GetTransport().GetGUID() != movementInfo.transport.guid)
                    {
                        plrMover.GetTransport().RemovePassenger(plrMover);
                        Transport transport = plrMover.GetMap().GetTransport(movementInfo.transport.guid);
                        if (transport)
                        {
                            transport.AddPassenger(plrMover);
                        }
                        else
                        {
                            movementInfo.ResetTransport();
                        }
                    }
                }

                if (!mover.GetTransport() && !mover.GetVehicle())
                {
                    GameObject go = mover.GetMap().GetGameObject(movementInfo.transport.guid);
                    if (!go || go.GetGoType() != GameObjectTypes.Transport)
                    {
                        movementInfo.transport.Reset();
                    }
                }
            }
            else if (plrMover && plrMover.GetTransport())                // if we were on a transport, leave
            {
                plrMover.GetTransport().RemovePassenger(plrMover);
            }

            // fall damage generation (ignore in flight case that can be triggered also at lags in moment teleportation to another map).
            if (opcode == ClientOpcodes.MoveFallLand && plrMover && !plrMover.IsInFlight())
            {
                plrMover.HandleFall(movementInfo);
            }

            if (plrMover && movementInfo.HasMovementFlag(MovementFlag.Swimming) != plrMover.IsInWater())
            {
                // now client not include swimming flag in case jumping under water
                plrMover.SetInWater(!plrMover.IsInWater() || plrMover.GetMap().IsUnderWater(movementInfo.Pos.posX, movementInfo.Pos.posY, movementInfo.Pos.posZ));
            }

            uint mstime = Time.GetMSTime();

            if (m_clientTimeDelay == 0)
            {
                m_clientTimeDelay = mstime - movementInfo.Time;
            }

            movementInfo.Time = movementInfo.Time + m_clientTimeDelay;

            movementInfo.Guid    = mover.GetGUID();
            mover.m_movementInfo = movementInfo;

            // Some vehicles allow the passenger to turn by himself
            Vehicle vehicle = mover.GetVehicle();

            if (vehicle)
            {
                VehicleSeatRecord seat = vehicle.GetSeatForPassenger(mover);
                if (seat != null)
                {
                    if (seat.Flags[0].HasAnyFlag((uint)VehicleSeatFlags.AllowTurning))
                    {
                        if (movementInfo.Pos.GetOrientation() != mover.GetOrientation())
                        {
                            mover.SetOrientation(movementInfo.Pos.GetOrientation());
                            mover.RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags.Turning);
                        }
                    }
                }
                return;
            }

            mover.UpdatePosition(movementInfo.Pos);

            MoveUpdate moveUpdate = new MoveUpdate();

            moveUpdate.movementInfo = mover.m_movementInfo;
            mover.SendMessageToSet(moveUpdate, GetPlayer());

            if (plrMover)                                            // nothing is charmed, or player charmed
            {
                if (plrMover.IsSitState() && movementInfo.HasMovementFlag(MovementFlag.MaskMoving | MovementFlag.MaskTurning))
                {
                    plrMover.SetStandState(UnitStandStateType.Stand);
                }

                plrMover.UpdateFallInformationIfNeed(movementInfo, opcode);

                if (movementInfo.Pos.posZ < plrMover.GetMap().GetMinHeight(movementInfo.Pos.GetPositionX(), movementInfo.Pos.GetPositionY()))
                {
                    if (!(plrMover.GetBattleground() && plrMover.GetBattleground().HandlePlayerUnderMap(GetPlayer())))
                    {
                        // NOTE: this is actually called many times while falling
                        // even after the player has been teleported away
                        /// @todo discard movement packets after the player is rooted
                        if (plrMover.IsAlive())
                        {
                            plrMover.SetFlag(PlayerFields.Flags, PlayerFlags.IsOutOfBounds);
                            plrMover.EnvironmentalDamage(EnviromentalDamage.FallToVoid, (uint)GetPlayer().GetMaxHealth());
                            // player can be alive if GM/etc
                            // change the death state to CORPSE to prevent the death timer from
                            // starting in the next player update
                            if (!plrMover.IsAlive())
                            {
                                plrMover.KillPlayer();
                            }
                        }
                    }
                }
                else
                {
                    plrMover.RemoveFlag(PlayerFields.Flags, PlayerFlags.IsOutOfBounds);
                }
            }
        }
        void HandleAuctionSellItem(AuctionSellItem packet)
        {
            foreach (var aitem in packet.Items)
            {
                if (aitem.Guid.IsEmpty() || aitem.UseCount == 0 || aitem.UseCount > 1000)
                {
                    return;
                }
            }

            if (packet.MinBid == 0 || packet.RunTime == 0)
            {
                return;
            }

            if (packet.MinBid > PlayerConst.MaxMoneyAmount || packet.BuyoutPrice > PlayerConst.MaxMoneyAmount)
            {
                Log.outDebug(LogFilter.Network, "WORLD: HandleAuctionSellItem - Player {0} ({1}) attempted to sell item with higher price than max gold amount.", GetPlayer().GetName(), GetPlayer().GetGUID().ToString());
                SendAuctionCommandResult(null, AuctionAction.SellItem, AuctionError.DatabaseError);
                return;
            }

            Creature creature = GetPlayer().GetNPCIfCanInteractWith(packet.Auctioneer, NPCFlags.Auctioneer);

            if (!creature)
            {
                Log.outDebug(LogFilter.Network, "WORLD: HandleAuctionSellItem - {0} not found or you can't interact with him.", packet.Auctioneer.ToString());
                return;
            }

            uint houseId = 0;
            AuctionHouseRecord auctionHouseEntry = Global.AuctionMgr.GetAuctionHouseEntry(creature.getFaction(), ref houseId);

            if (auctionHouseEntry == null)
            {
                Log.outDebug(LogFilter.Network, "WORLD: HandleAuctionSellItem - {0} has wrong faction.", packet.Auctioneer.ToString());
                return;
            }

            packet.RunTime *= Time.Minute;
            switch (packet.RunTime)
            {
            case 1 * SharedConst.MinAuctionTime:
            case 2 * SharedConst.MinAuctionTime:
            case 4 * SharedConst.MinAuctionTime:
                break;

            default:
                return;
            }

            if (GetPlayer().HasUnitState(UnitState.Died))
            {
                GetPlayer().RemoveAurasByType(AuraType.FeignDeath);
            }

            uint finalCount = 0;

            foreach (var packetItem in packet.Items)
            {
                Item aitem = GetPlayer().GetItemByGuid(packetItem.Guid);
                if (!aitem)
                {
                    SendAuctionCommandResult(null, AuctionAction.SellItem, AuctionError.ItemNotFound);
                    return;
                }

                if (Global.AuctionMgr.GetAItem(aitem.GetGUID().GetCounter()) || !aitem.CanBeTraded() || aitem.IsNotEmptyBag() ||
                    aitem.GetTemplate().GetFlags().HasAnyFlag(ItemFlags.Conjured) || aitem.GetUInt32Value(ItemFields.Duration) != 0 ||
                    aitem.GetCount() < packetItem.UseCount)
                {
                    SendAuctionCommandResult(null, AuctionAction.SellItem, AuctionError.DatabaseError);
                    return;
                }

                finalCount += packetItem.UseCount;
            }

            if (packet.Items.Empty())
            {
                SendAuctionCommandResult(null, AuctionAction.SellItem, AuctionError.DatabaseError);
                return;
            }

            if (finalCount == 0)
            {
                SendAuctionCommandResult(null, AuctionAction.SellItem, AuctionError.DatabaseError);
                return;
            }

            // check if there are 2 identical guids, in this case user is most likely cheating
            for (int i = 0; i < packet.Items.Count; ++i)
            {
                for (int j = i + 1; j < packet.Items.Count; ++j)
                {
                    if (packet.Items[i].Guid == packet.Items[j].Guid)
                    {
                        SendAuctionCommandResult(null, AuctionAction.SellItem, AuctionError.DatabaseError);
                        return;
                    }
                }
            }

            foreach (var packetItem in packet.Items)
            {
                Item aitem = GetPlayer().GetItemByGuid(packetItem.Guid);

                if (aitem.GetMaxStackCount() < finalCount)
                {
                    SendAuctionCommandResult(null, AuctionAction.SellItem, AuctionError.DatabaseError);
                    return;
                }
            }

            Item item = GetPlayer().GetItemByGuid(packet.Items[0].Guid);

            uint auctionTime = (uint)(packet.RunTime * WorldConfig.GetFloatValue(WorldCfg.RateAuctionTime));
            AuctionHouseObject auctionHouse = Global.AuctionMgr.GetAuctionsMap(creature.getFaction());

            ulong deposit = Global.AuctionMgr.GetAuctionDeposit(auctionHouseEntry, packet.RunTime, item, finalCount);

            if (!GetPlayer().HasEnoughMoney(deposit))
            {
                SendAuctionCommandResult(null, AuctionAction.SellItem, AuctionError.NotEnoughtMoney);
                return;
            }

            AuctionEntry   AH = new AuctionEntry();
            SQLTransaction trans;

            if (WorldConfig.GetBoolValue(WorldCfg.AllowTwoSideInteractionAuction))
            {
                AH.auctioneer = 23442;     ///@TODO - HARDCODED DB GUID, BAD BAD BAD
            }
            else
            {
                AH.auctioneer = creature.GetSpawnId();
            }

            // Required stack size of auction matches to current item stack size, just move item to auctionhouse
            if (packet.Items.Count == 1 && item.GetCount() == packet.Items[0].UseCount)
            {
                if (HasPermission(RBACPermissions.LogGmTrade))
                {
                    Log.outCommand(GetAccountId(), "GM {0} (Account: {1}) create auction: {2} (Entry: {3} Count: {4})",
                                   GetPlayerName(), GetAccountId(), item.GetTemplate().GetName(), item.GetEntry(), item.GetCount());
                }

                AH.Id                = Global.ObjectMgr.GenerateAuctionID();
                AH.itemGUIDLow       = item.GetGUID().GetCounter();
                AH.itemEntry         = item.GetEntry();
                AH.itemCount         = item.GetCount();
                AH.owner             = GetPlayer().GetGUID().GetCounter();
                AH.startbid          = (uint)packet.MinBid;
                AH.bidder            = 0;
                AH.bid               = 0;
                AH.buyout            = (uint)packet.BuyoutPrice;
                AH.expire_time       = Time.UnixTime + auctionTime;
                AH.deposit           = deposit;
                AH.etime             = packet.RunTime;
                AH.auctionHouseEntry = auctionHouseEntry;

                Log.outInfo(LogFilter.Network, "CMSG_AUCTION_SELL_ITEM: {0} {1} is selling item {2} {3} to auctioneer {4} with count {5} with initial bid {6} with buyout {7} and with time {8} (in sec) in auctionhouse {9}",
                            GetPlayer().GetGUID().ToString(), GetPlayer().GetName(), item.GetGUID().ToString(), item.GetTemplate().GetName(), AH.auctioneer, item.GetCount(), packet.MinBid, packet.BuyoutPrice, auctionTime, AH.GetHouseId());
                Global.AuctionMgr.AddAItem(item);
                auctionHouse.AddAuction(AH);

                GetPlayer().MoveItemFromInventory(item.GetBagSlot(), item.GetSlot(), true);

                trans = new SQLTransaction();
                item.DeleteFromInventoryDB(trans);
                item.SaveToDB(trans);
                AH.SaveToDB(trans);
                GetPlayer().SaveInventoryAndGoldToDB(trans);
                DB.Characters.CommitTransaction(trans);

                SendAuctionCommandResult(AH, AuctionAction.SellItem, AuctionError.Ok);

                GetPlayer().UpdateCriteria(CriteriaTypes.CreateAuction, 1);
            }
            else // Required stack size of auction does not match to current item stack size, clone item and set correct stack size
            {
                Item newItem = item.CloneItem(finalCount, GetPlayer());
                if (!newItem)
                {
                    Log.outError(LogFilter.Network, "CMSG_AuctionAction.SellItem: Could not create clone of item {0}", item.GetEntry());
                    SendAuctionCommandResult(null, AuctionAction.SellItem, AuctionError.DatabaseError);
                    return;
                }

                if (HasPermission(RBACPermissions.LogGmTrade))
                {
                    Log.outCommand(GetAccountId(), "GM {0} (Account: {1}) create auction: {2} (Entry: {3} Count: {4})",
                                   GetPlayerName(), GetAccountId(), newItem.GetTemplate().GetName(), newItem.GetEntry(), newItem.GetCount());
                }

                AH.Id                = Global.ObjectMgr.GenerateAuctionID();
                AH.itemGUIDLow       = newItem.GetGUID().GetCounter();
                AH.itemEntry         = newItem.GetEntry();
                AH.itemCount         = newItem.GetCount();
                AH.owner             = GetPlayer().GetGUID().GetCounter();
                AH.startbid          = (uint)packet.MinBid;
                AH.bidder            = 0;
                AH.bid               = 0;
                AH.buyout            = (uint)packet.BuyoutPrice;
                AH.expire_time       = Time.UnixTime + auctionTime;
                AH.deposit           = deposit;
                AH.etime             = packet.RunTime;
                AH.auctionHouseEntry = auctionHouseEntry;

                Log.outInfo(LogFilter.Network, "CMSG_AuctionAction.SellItem: {0} {1} is selling {2} {3} to auctioneer {4} with count {5} with initial bid {6} with buyout {7} and with time {8} (in sec) in auctionhouse {9}",
                            GetPlayer().GetGUID().ToString(), GetPlayer().GetName(), newItem.GetGUID().ToString(), newItem.GetTemplate().GetName(), AH.auctioneer, newItem.GetCount(), packet.MinBid, packet.BuyoutPrice, auctionTime, AH.GetHouseId());
                Global.AuctionMgr.AddAItem(newItem);
                auctionHouse.AddAuction(AH);

                foreach (var packetItem in packet.Items)
                {
                    Item item2 = GetPlayer().GetItemByGuid(packetItem.Guid);

                    // Item stack count equals required count, ready to delete item - cloned item will be used for auction
                    if (item2.GetCount() == packetItem.UseCount)
                    {
                        GetPlayer().MoveItemFromInventory(item2.GetBagSlot(), item2.GetSlot(), true);

                        trans = new SQLTransaction();
                        item2.DeleteFromInventoryDB(trans);
                        item2.DeleteFromDB(trans);
                        DB.Characters.CommitTransaction(trans);
                    }
                    else // Item stack count is bigger than required count, update item stack count and save to database - cloned item will be used for auction
                    {
                        item2.SetCount(item2.GetCount() - packetItem.UseCount);
                        item2.SetState(ItemUpdateState.Changed, GetPlayer());
                        GetPlayer().ItemRemovedQuestCheck(item2.GetEntry(), packetItem.UseCount);
                        item2.SendUpdateToPlayer(GetPlayer());

                        trans = new SQLTransaction();
                        item2.SaveToDB(trans);
                        DB.Characters.CommitTransaction(trans);
                    }
                }

                trans = new SQLTransaction();
                newItem.SaveToDB(trans);
                AH.SaveToDB(trans);
                GetPlayer().SaveInventoryAndGoldToDB(trans);
                DB.Characters.CommitTransaction(trans);

                SendAuctionCommandResult(AH, AuctionAction.SellItem, AuctionError.Ok);

                GetPlayer().UpdateCriteria(CriteriaTypes.CreateAuction, 1);
            }

            GetPlayer().ModifyMoney(-(long)deposit);
        }
Exemple #17
0
        public bool ReGenerate()
        {
            if (m_weatherChances == null)
            {
                m_type  = WeatherType.Fine;
                m_grade = 0.0f;
                return(false);
            }

            // Weather statistics:
            // 30% - no change
            // 30% - weather gets better (if not fine) or change weather type
            // 30% - weather worsens (if not fine)
            // 10% - radical change (if not fine)
            uint u = RandomHelper.URand(0, 99);

            if (u < 30)
            {
                return(false);
            }

            // remember old values
            WeatherType old_type  = m_type;
            float       old_grade = m_grade;

            long gtime  = Global.WorldMgr.GetGameTime();
            var  ltime  = Time.UnixTimeToDateTime(gtime).ToLocalTime();
            uint season = (uint)((ltime.DayOfYear - 78 + 365) / 91) % 4;

            string[] seasonName = { "spring", "summer", "fall", "winter" };

            Log.outError(LogFilter.Server, "Generating a change in {0} weather for zone {1}.", seasonName[season], m_zone);

            if ((u < 60) && (m_grade < 0.33333334f))                // Get fair
            {
                m_type  = WeatherType.Fine;
                m_grade = 0.0f;
            }

            if ((u < 60) && (m_type != WeatherType.Fine))          // Get better
            {
                m_grade -= 0.33333334f;
                return(true);
            }

            if ((u < 90) && (m_type != WeatherType.Fine))          // Get worse
            {
                m_grade += 0.33333334f;
                return(true);
            }

            if (m_type != WeatherType.Fine)
            {
                // Radical change:
                // if light . heavy
                // if medium . change weather type
                // if heavy . 50% light, 50% change weather type

                if (m_grade < 0.33333334f)
                {
                    m_grade = 0.9999f;                              // go nuts
                    return(true);
                }
                else
                {
                    if (m_grade > 0.6666667f)
                    {
                        // Severe change, but how severe?
                        uint rnd = RandomHelper.URand(0, 99);
                        if (rnd < 50)
                        {
                            m_grade -= 0.6666667f;
                            return(true);
                        }
                    }
                    m_type  = WeatherType.Fine;                    // clear up
                    m_grade = 0;
                }
            }

            // At this point, only weather that isn't doing anything remains but that have weather data
            uint chance1 = m_weatherChances.data[season].rainChance;
            uint chance2 = chance1 + m_weatherChances.data[season].snowChance;
            uint chance3 = chance2 + m_weatherChances.data[season].stormChance;
            uint rn      = RandomHelper.URand(1, 100);

            if (rn <= chance1)
            {
                m_type = WeatherType.Rain;
            }
            else if (rn <= chance2)
            {
                m_type = WeatherType.Snow;
            }
            else if (rn <= chance3)
            {
                m_type = WeatherType.Storm;
            }
            else
            {
                m_type = WeatherType.Fine;
            }

            // New weather statistics (if not fine):
            // 85% light
            // 7% medium
            // 7% heavy
            // If fine 100% sun (no fog)

            if (m_type == WeatherType.Fine)
            {
                m_grade = 0.0f;
            }
            else if (u < 90)
            {
                m_grade = (float)RandomHelper.NextDouble() * 0.3333f;
            }
            else
            {
                // Severe change, but how severe?
                rn = RandomHelper.URand(0, 99);
                if (rn < 50)
                {
                    m_grade = (float)RandomHelper.NextDouble() * 0.3333f + 0.3334f;
                }
                else
                {
                    m_grade = (float)RandomHelper.NextDouble() * 0.3333f + 0.6667f;
                }
            }

            // return true only in case weather changes
            return(m_type != old_type || m_grade != old_grade);
        }
        void HandleAuctionRemoveItem(AuctionRemoveItem packet)
        {
            Creature creature = GetPlayer().GetNPCIfCanInteractWith(packet.Auctioneer, NPCFlags.Auctioneer);

            if (!creature)
            {
                Log.outDebug(LogFilter.Network, "WORLD: HandleAuctionRemoveItem - {0} not found or you can't interact with him.", packet.Auctioneer.ToString());
                return;
            }

            // remove fake death
            if (GetPlayer().HasUnitState(UnitState.Died))
            {
                GetPlayer().RemoveAurasByType(AuraType.FeignDeath);
            }

            AuctionHouseObject auctionHouse = Global.AuctionMgr.GetAuctionsMap(creature.getFaction());

            AuctionEntry auction = auctionHouse.GetAuction((uint)packet.AuctionItemID);
            Player       player  = GetPlayer();

            SQLTransaction trans = new SQLTransaction();

            if (auction != null && auction.owner == player.GetGUID().GetCounter())
            {
                Item pItem = Global.AuctionMgr.GetAItem(auction.itemGUIDLow);
                if (pItem)
                {
                    if (auction.bidder > 0)                        // If we have a bidder, we have to send him the money he paid
                    {
                        ulong auctionCut = auction.GetAuctionCut();
                        if (!player.HasEnoughMoney(auctionCut))          //player doesn't have enough money, maybe message needed
                        {
                            return;
                        }
                        Global.AuctionMgr.SendAuctionCancelledToBidderMail(auction, trans);
                        player.ModifyMoney(-(long)auctionCut);
                    }

                    // item will deleted or added to received mail list
                    new MailDraft(auction.BuildAuctionMailSubject(MailAuctionAnswers.Canceled), AuctionEntry.BuildAuctionMailBody(0, 0, auction.buyout, auction.deposit, 0))
                    .AddItem(pItem)
                    .SendMailTo(trans, new MailReceiver(player), new MailSender(auction), MailCheckMask.Copied);
                }
                else
                {
                    Log.outError(LogFilter.Network, "Auction id: {0} got non existing item (item guid : {1})!", auction.Id, auction.itemGUIDLow);
                    SendAuctionCommandResult(null, AuctionAction.Cancel, AuctionError.DatabaseError);
                    return;
                }
            }
            else
            {
                SendAuctionCommandResult(null, AuctionAction.Cancel, AuctionError.DatabaseError);
                //this code isn't possible ... maybe there should be assert
                Log.outError(LogFilter.Network, "CHEATER: {0} tried to cancel auction (id: {1}) of another player or auction is null", player.GetGUID().ToString(), packet.AuctionItemID);
                return;
            }

            //inform player, that auction is removed
            SendAuctionCommandResult(auction, AuctionAction.Cancel, AuctionError.Ok);

            // Now remove the auction
            player.SaveInventoryAndGoldToDB(trans);
            auction.DeleteFromDB(trans);
            DB.Characters.CommitTransaction(trans);

            Global.AuctionMgr.RemoveAItem(auction.itemGUIDLow);
            auctionHouse.RemoveAuction(auction);
        }
Exemple #19
0
        void HandleForceSpeedChangeAck(MovementSpeedAck packet)
        {
            GetPlayer().ValidateMovementInfo(packet.Ack.Status);

            // now can skip not our packet
            if (GetPlayer().GetGUID() != packet.Ack.Status.Guid)
            {
                return;
            }

            /*----------------*/
            // client ACK send one packet for mounted/run case and need skip all except last from its
            // in other cases anti-cheat check can be fail in false case
            UnitMoveType move_type;

            ClientOpcodes opcode = packet.GetOpcode();

            switch (opcode)
            {
            case ClientOpcodes.MoveForceWalkSpeedChangeAck:
                move_type = UnitMoveType.Walk;
                break;

            case ClientOpcodes.MoveForceRunSpeedChangeAck:
                move_type = UnitMoveType.Run;
                break;

            case ClientOpcodes.MoveForceRunBackSpeedChangeAck:
                move_type = UnitMoveType.RunBack;
                break;

            case ClientOpcodes.MoveForceSwimSpeedChangeAck:
                move_type = UnitMoveType.Swim;
                break;

            case ClientOpcodes.MoveForceSwimBackSpeedChangeAck:
                move_type = UnitMoveType.SwimBack;
                break;

            case ClientOpcodes.MoveForceTurnRateChangeAck:
                move_type = UnitMoveType.TurnRate;
                break;

            case ClientOpcodes.MoveForceFlightSpeedChangeAck:
                move_type = UnitMoveType.Flight;
                break;

            case ClientOpcodes.MoveForceFlightBackSpeedChangeAck:
                move_type = UnitMoveType.FlightBack;
                break;

            case ClientOpcodes.MoveForcePitchRateChangeAck:
                move_type = UnitMoveType.PitchRate;
                break;

            default:
                Log.outError(LogFilter.Network, "WorldSession.HandleForceSpeedChangeAck: Unknown move type opcode: {0}", opcode);
                return;
            }

            // skip all forced speed changes except last and unexpected
            // in run/mounted case used one ACK and it must be skipped. m_forced_speed_changes[MOVE_RUN] store both.
            if (GetPlayer().m_forced_speed_changes[(int)move_type] > 0)
            {
                --GetPlayer().m_forced_speed_changes[(int)move_type];
                if (GetPlayer().m_forced_speed_changes[(int)move_type] > 0)
                {
                    return;
                }
            }

            if (!GetPlayer().GetTransport() && Math.Abs(GetPlayer().GetSpeed(move_type) - packet.Speed) > 0.01f)
            {
                if (GetPlayer().GetSpeed(move_type) > packet.Speed)         // must be greater - just correct
                {
                    Log.outError(LogFilter.Network, "{0}SpeedChange player {1} is NOT correct (must be {2} instead {3}), force set to correct value",
                                 move_type, GetPlayer().GetName(), GetPlayer().GetSpeed(move_type), packet.Speed);
                    GetPlayer().SetSpeedRate(move_type, GetPlayer().GetSpeedRate(move_type));
                }
                else                                                // must be lesser - cheating
                {
                    Log.outDebug(LogFilter.Server, "Player {0} from account id {1} kicked for incorrect speed (must be {2} instead {3})",
                                 GetPlayer().GetName(), GetPlayer().GetSession().GetAccountId(), GetPlayer().GetSpeed(move_type), packet.Speed);
                    GetPlayer().GetSession().KickPlayer();
                }
            }
        }
Exemple #20
0
        public bool Update(uint diff, PacketFilter updater)
        {
            // Update Timeout timer.
            UpdateTimeOutTime(diff);

            // Before we process anything:
            // If necessary, kick the player from the character select screen
            if (IsConnectionIdle())
            {
                m_Socket[(int)ConnectionType.Realm].CloseSocket();
            }

            WorldPacket firstDelayedPacket = null;
            uint        processedPackets   = 0;
            long        currentTime        = Time.UnixTime;

            WorldPacket packet;

            //Check for any packets they was not recived yet.
            while (m_Socket[(int)ConnectionType.Realm] != null && !_recvQueue.IsEmpty && (_recvQueue.TryPeek(out packet, updater) && packet != firstDelayedPacket) && _recvQueue.TryDequeue(out packet))
            {
                try
                {
                    var handler = PacketManager.GetHandler((ClientOpcodes)packet.GetOpcode());
                    switch (handler.sessionStatus)
                    {
                    case SessionStatus.Loggedin:
                        if (!_player)
                        {
                            if (!m_playerRecentlyLogout)
                            {
                                if (firstDelayedPacket == null)
                                {
                                    firstDelayedPacket = packet;
                                }

                                QueuePacket(packet);
                                Log.outDebug(LogFilter.Network, "Re-enqueueing packet with opcode {0} with with status OpcodeStatus.Loggedin. Player is currently not in world yet.", (ClientOpcodes)packet.GetOpcode());
                            }
                            break;
                        }
                        else if (_player.IsInWorld && AntiDOS.EvaluateOpcode(packet, currentTime))
                        {
                            handler.Invoke(this, packet);
                        }
                        break;

                    case SessionStatus.LoggedinOrRecentlyLogout:
                        if (!_player && !m_playerRecentlyLogout && !m_playerLogout)
                        {
                            LogUnexpectedOpcode(packet, handler.sessionStatus, "the player has not logged in yet and not recently logout");
                        }
                        else if (AntiDOS.EvaluateOpcode(packet, currentTime))
                        {
                            handler.Invoke(this, packet);
                        }
                        break;

                    case SessionStatus.Transfer:
                        if (!_player)
                        {
                            LogUnexpectedOpcode(packet, handler.sessionStatus, "the player has not logged in yet");
                        }
                        else if (_player.IsInWorld)
                        {
                            LogUnexpectedOpcode(packet, handler.sessionStatus, "the player is still in world");
                        }
                        else if (AntiDOS.EvaluateOpcode(packet, currentTime))
                        {
                            handler.Invoke(this, packet);
                        }
                        break;

                    case SessionStatus.Authed:
                        // prevent cheating with skip queue wait
                        if (m_inQueue)
                        {
                            LogUnexpectedOpcode(packet, handler.sessionStatus, "the player not pass queue yet");
                            break;
                        }

                        if ((ClientOpcodes)packet.GetOpcode() == ClientOpcodes.EnumCharacters)
                        {
                            m_playerRecentlyLogout = false;
                        }

                        if (AntiDOS.EvaluateOpcode(packet, currentTime))
                        {
                            handler.Invoke(this, packet);
                        }
                        break;

                    default:
                        Log.outError(LogFilter.Network, "Received not handled opcode {0} from {1}", (ClientOpcodes)packet.GetOpcode(), GetPlayerInfo());
                        break;
                    }
                }
                catch (InternalBufferOverflowException ex)
                {
                    Log.outError(LogFilter.Network, "InternalBufferOverflowException: {0} while parsing {1} from {2}.", ex.Message, (ClientOpcodes)packet.GetOpcode(), GetPlayerInfo());
                }
                catch (EndOfStreamException)
                {
                    Log.outError(LogFilter.Network, "WorldSession:Update EndOfStreamException occured while parsing a packet (opcode: {0}) from client {1}, accountid={2}. Skipped packet.",
                                 (ClientOpcodes)packet.GetOpcode(), GetRemoteAddress(), GetAccountId());
                }

                processedPackets++;

                if (processedPackets > 100)
                {
                    break;
                }
            }

            if (m_Socket[(int)ConnectionType.Realm] != null && m_Socket[(int)ConnectionType.Realm].IsOpen() && _warden != null)
            {
                _warden.Update();
            }

            ProcessQueryCallbacks();

            if (updater.ProcessUnsafe())
            {
                long currTime = Time.UnixTime;
                // If necessary, log the player out
                if (ShouldLogOut(currTime) && m_playerLoading.IsEmpty())
                {
                    LogoutPlayer(true);
                }

                if (m_Socket[(int)ConnectionType.Realm] != null && GetPlayer() && _warden != null)
                {
                    _warden.Update();
                }

                //- Cleanup socket if need
                if ((m_Socket[(int)ConnectionType.Realm] != null && !m_Socket[(int)ConnectionType.Realm].IsOpen()) ||
                    (m_Socket[(int)ConnectionType.Instance] != null && !m_Socket[(int)ConnectionType.Instance].IsOpen()))
                {
                    expireTime -= expireTime > diff ? diff : expireTime;
                    if (expireTime < diff || forceExit || !GetPlayer())
                    {
                        if (m_Socket[(int)ConnectionType.Realm] != null)
                        {
                            m_Socket[(int)ConnectionType.Realm].CloseSocket();
                            m_Socket[(int)ConnectionType.Realm] = null;
                        }
                        if (m_Socket[(int)ConnectionType.Instance] != null)
                        {
                            m_Socket[(int)ConnectionType.Instance].CloseSocket();
                            m_Socket[(int)ConnectionType.Instance] = null;
                        }
                    }
                }

                if (m_Socket[(int)ConnectionType.Realm] == null)
                {
                    return(false);                                       //Will remove this session from the world session map
                }
            }

            return(true);
        }
        void HandleQuestgiverChooseReward(QuestGiverChooseReward packet)
        {
            Quest quest = Global.ObjectMgr.GetQuestTemplate(packet.QuestID);

            if (quest == null)
            {
                return;
            }

            // This is Real Item Entry, not slot id as pre 5.x
            if (packet.ItemChoiceID != 0)
            {
                ItemTemplate rewardProto = Global.ObjectMgr.GetItemTemplate(packet.ItemChoiceID);
                if (rewardProto == null)
                {
                    Log.outError(LogFilter.Network, "Error in CMSG_QUESTGIVER_CHOOSE_REWARD: player {0} ({1}) tried to get invalid reward item (Item Entry: {2}) for quest {3} (possible packet-hacking detected)", GetPlayer().GetName(), GetPlayer().GetGUID().ToString(), packet.ItemChoiceID, packet.QuestID);
                    return;
                }

                bool itemValid = false;
                for (uint i = 0; i < quest.GetRewChoiceItemsCount(); ++i)
                {
                    if (quest.RewardChoiceItemId[i] != 0 && quest.RewardChoiceItemId[i] == packet.ItemChoiceID)
                    {
                        itemValid = true;
                        break;
                    }
                }

                if (!itemValid && quest.PackageID != 0)
                {
                    var questPackageItems = Global.DB2Mgr.GetQuestPackageItems(quest.PackageID);
                    if (questPackageItems != null)
                    {
                        foreach (var questPackageItem in questPackageItems)
                        {
                            if (questPackageItem.ItemID != packet.ItemChoiceID)
                            {
                                continue;
                            }

                            if (_player.CanSelectQuestPackageItem(questPackageItem))
                            {
                                itemValid = true;
                                break;
                            }
                        }
                    }

                    if (!itemValid)
                    {
                        var questPackageItems1 = Global.DB2Mgr.GetQuestPackageItemsFallback(quest.PackageID);
                        if (questPackageItems1 != null)
                        {
                            foreach (var questPackageItem in questPackageItems1)
                            {
                                if (questPackageItem.ItemID != packet.ItemChoiceID)
                                {
                                    continue;
                                }

                                itemValid = true;
                                break;
                            }
                        }
                    }
                }

                if (!itemValid)
                {
                    Log.outError(LogFilter.Network, "Error in CMSG_QUESTGIVER_CHOOSE_REWARD: player {0} ({1}) tried to get reward item (Item Entry: {2}) wich is not a reward for quest {3} (possible packet-hacking detected)", GetPlayer().GetName(), GetPlayer().GetGUID().ToString(), packet.ItemChoiceID, packet.QuestID);
                    return;
                }
            }

            WorldObject obj = GetPlayer();

            if (!quest.HasFlag(QuestFlags.AutoComplete))
            {
                obj = Global.ObjAccessor.GetObjectByTypeMask(GetPlayer(), packet.QuestGiverGUID, TypeMask.Unit | TypeMask.GameObject);
                if (!obj || !obj.HasInvolvedQuest(packet.QuestID))
                {
                    return;
                }

                // some kind of WPE protection
                if (!GetPlayer().CanInteractWithQuestGiver(obj))
                {
                    return;
                }
            }

            if ((!GetPlayer().CanSeeStartQuest(quest) && GetPlayer().GetQuestStatus(packet.QuestID) == QuestStatus.None) ||
                (GetPlayer().GetQuestStatus(packet.QuestID) != QuestStatus.Complete && !quest.IsAutoComplete()))
            {
                Log.outError(LogFilter.Network, "Error in QuestStatus.Complete: player {0} ({1}) tried to complete quest {2}, but is not allowed to do so (possible packet-hacking or high latency)",
                             GetPlayer().GetName(), GetPlayer().GetGUID().ToString(), packet.QuestID);
                return;
            }

            if (GetPlayer().CanRewardQuest(quest, packet.ItemChoiceID, true))
            {
                GetPlayer().RewardQuest(quest, packet.ItemChoiceID, obj);

                switch (obj.GetTypeId())
                {
                case TypeId.Unit:
                case TypeId.Player:
                {
                    //For AutoSubmition was added plr case there as it almost same exclute AI script cases.
                    Creature creatureQGiver = obj.ToCreature();
                    if (!creatureQGiver || !Global.ScriptMgr.OnQuestReward(GetPlayer(), creatureQGiver, quest, packet.ItemChoiceID))
                    {
                        // Send next quest
                        Quest nextQuest = GetPlayer().GetNextQuest(packet.QuestGiverGUID, quest);
                        if (nextQuest != null)
                        {
                            // Only send the quest to the player if the conditions are met
                            if (GetPlayer().CanTakeQuest(nextQuest, false))
                            {
                                if (nextQuest.IsAutoAccept() && GetPlayer().CanAddQuest(nextQuest, true))
                                {
                                    GetPlayer().AddQuestAndCheckCompletion(nextQuest, obj);
                                }

                                GetPlayer().PlayerTalkClass.SendQuestGiverQuestDetails(nextQuest, packet.QuestGiverGUID, true, false);
                            }
                        }

                        if (creatureQGiver)
                        {
                            creatureQGiver.GetAI().QuestReward(GetPlayer(), quest, packet.ItemChoiceID);
                        }
                    }
                    break;
                }

                case TypeId.GameObject:
                    GameObject questGiver = obj.ToGameObject();
                    if (!Global.ScriptMgr.OnQuestReward(GetPlayer(), questGiver, quest, packet.ItemChoiceID))
                    {
                        // Send next quest
                        Quest nextQuest = GetPlayer().GetNextQuest(packet.QuestGiverGUID, quest);
                        if (nextQuest != null)
                        {
                            // Only send the quest to the player if the conditions are met
                            if (GetPlayer().CanTakeQuest(nextQuest, false))
                            {
                                if (nextQuest.IsAutoAccept() && GetPlayer().CanAddQuest(nextQuest, true))
                                {
                                    GetPlayer().AddQuestAndCheckCompletion(nextQuest, obj);
                                }

                                GetPlayer().PlayerTalkClass.SendQuestGiverQuestDetails(nextQuest, packet.QuestGiverGUID, true, false);
                            }
                        }

                        questGiver.GetAI().QuestReward(GetPlayer(), quest, packet.ItemChoiceID);
                    }
                    break;

                default:
                    break;
                }
            }
            else
            {
                GetPlayer().PlayerTalkClass.SendQuestGiverOfferReward(quest, packet.QuestGiverGUID, true);
            }
        }
Exemple #22
0
 void LogUnexpectedOpcode(WorldPacket packet, SessionStatus status, string reason)
 {
     Log.outError(LogFilter.Network, "Received unexpected opcode {0} Status: {1} Reason: {2} from {3}", (ClientOpcodes)packet.GetOpcode(), status, reason, GetPlayerInfo());
 }
        void HandlePlayerChoiceResponse(ChoiceResponse choiceResponse)
        {
            if (_player.PlayerTalkClass.GetInteractionData().PlayerChoiceId != choiceResponse.ChoiceID)
            {
                Log.outError(LogFilter.Player, $"Error in CMSG_CHOICE_RESPONSE: {GetPlayerInfo()} tried to respond to invalid player choice {choiceResponse.ChoiceID} (allowed {_player.PlayerTalkClass.GetInteractionData().PlayerChoiceId}) (possible packet-hacking detected)");
                return;
            }

            PlayerChoice playerChoice = Global.ObjectMgr.GetPlayerChoice(choiceResponse.ChoiceID);

            if (playerChoice == null)
            {
                return;
            }

            PlayerChoiceResponse playerChoiceResponse = playerChoice.GetResponse(choiceResponse.ResponseID);

            if (playerChoiceResponse == null)
            {
                Log.outError(LogFilter.Player, $"Error in CMSG_CHOICE_RESPONSE: {GetPlayerInfo()} tried to select invalid player choice response {choiceResponse.ResponseID} (possible packet-hacking detected)");
                return;
            }

            Global.ScriptMgr.OnPlayerChoiceResponse(GetPlayer(), (uint)choiceResponse.ChoiceID, (uint)choiceResponse.ResponseID);

            if (playerChoiceResponse.Reward.HasValue)
            {
                var reward = playerChoiceResponse.Reward.Value;
                if (reward.TitleId != 0)
                {
                    _player.SetTitle(CliDB.CharTitlesStorage.LookupByKey(reward.TitleId), false);
                }

                if (reward.PackageId != 0)
                {
                    _player.RewardQuestPackage((uint)reward.PackageId);
                }

                if (reward.SkillLineId != 0 && _player.HasSkill((SkillType)reward.SkillLineId))
                {
                    _player.UpdateSkillPro((uint)reward.SkillLineId, 1000, reward.SkillPointCount);
                }

                if (reward.HonorPointCount != 0)
                {
                    _player.AddHonorXP(reward.HonorPointCount);
                }

                if (reward.Money != 0)
                {
                    _player.ModifyMoney((long)reward.Money, false);
                }

                if (reward.Xp != 0)
                {
                    _player.GiveXP(reward.Xp, null, 0.0f);
                }

                foreach (PlayerChoiceResponseRewardItem item in reward.Items)
                {
                    List <ItemPosCount> dest = new List <ItemPosCount>();
                    if (_player.CanStoreNewItem(ItemConst.NullBag, ItemConst.NullSlot, dest, item.Id, (uint)item.Quantity) == InventoryResult.Ok)
                    {
                        Item newItem = _player.StoreNewItem(dest, item.Id, true, ItemEnchantmentManager.GenerateItemRandomBonusListId(item.Id), null, ItemContext.QuestReward, item.BonusListIDs);
                        _player.SendNewItem(newItem, (uint)item.Quantity, true, false);
                    }
                }

                foreach (PlayerChoiceResponseRewardEntry currency in reward.Currency)
                {
                    _player.ModifyCurrency((CurrencyTypes)currency.Id, currency.Quantity);
                }

                foreach (PlayerChoiceResponseRewardEntry faction in reward.Faction)
                {
                    _player.GetReputationMgr().ModifyReputation(CliDB.FactionStorage.LookupByKey(faction.Id), faction.Quantity);
                }
            }
        }
Exemple #24
0
        public void LoadRBAC()
        {
            ClearRBAC();

            Log.outDebug(LogFilter.Rbac, "AccountMgr:LoadRBAC");
            uint oldMSTime = Time.GetMSTime();
            uint count1    = 0;
            uint count2    = 0;
            uint count3    = 0;

            Log.outDebug(LogFilter.Rbac, "AccountMgr:LoadRBAC: Loading permissions");
            SQLResult result = DB.Login.Query("SELECT id, name FROM rbac_permissions");

            if (result.IsEmpty())
            {
                Log.outInfo(LogFilter.ServerLoading, "Loaded 0 account permission definitions. DB table `rbac_permissions` is empty.");
                return;
            }

            do
            {
                uint id = result.Read <uint>(0);
                _permissions[id] = new RBACPermission(id, result.Read <string>(1));
                ++count1;
            }while (result.NextRow());

            Log.outDebug(LogFilter.Rbac, "AccountMgr:LoadRBAC: Loading linked permissions");
            result = DB.Login.Query("SELECT id, linkedId FROM rbac_linked_permissions ORDER BY id ASC");
            if (result.IsEmpty())
            {
                Log.outInfo(LogFilter.ServerLoading, "Loaded 0 linked permissions. DB table `rbac_linked_permissions` is empty.");
                return;
            }

            uint           permissionId = 0;
            RBACPermission permission   = null;

            do
            {
                uint newId = result.Read <uint>(0);
                if (permissionId != newId)
                {
                    permissionId = newId;
                    permission   = _permissions[newId];
                }

                uint linkedPermissionId = result.Read <uint>(1);
                if (linkedPermissionId == permissionId)
                {
                    Log.outError(LogFilter.Sql, "RBAC Permission {0} has itself as linked permission. Ignored", permissionId);
                    continue;
                }
                permission.AddLinkedPermission(linkedPermissionId);
                ++count2;
            }while (result.NextRow());

            Log.outDebug(LogFilter.Rbac, "AccountMgr:LoadRBAC: Loading default permissions");
            result = DB.Login.Query("SELECT secId, permissionId FROM rbac_default_permissions ORDER BY secId ASC");
            if (result.IsEmpty())
            {
                Log.outInfo(LogFilter.ServerLoading, "Loaded 0 default permission definitions. DB table `rbac_default_permissions` is empty.");
                return;
            }

            uint secId = 255;

            do
            {
                uint newId = result.Read <uint>(0);
                if (secId != newId)
                {
                    secId = newId;
                }

                _defaultPermissions.Add((byte)secId, result.Read <uint>(1));
                ++count3;
            }while (result.NextRow());

            Log.outInfo(LogFilter.ServerLoading, "Loaded {0} permission definitions, {1} linked permissions and {2} default permissions in {3} ms", count1, count2, count3, Time.GetMSTimeDiffToNow(oldMSTime));
        }
        public void LoadCreatureTexts()
        {
            uint oldMSTime = Time.GetMSTime();

            mTextMap.Clear(); // for reload case
            //all currently used temp texts are NOT reset

            PreparedStatement stmt   = DB.World.GetPreparedStatement(WorldStatements.SEL_CREATURE_TEXT);
            SQLResult         result = DB.World.Query(stmt);

            if (result.IsEmpty())
            {
                Log.outInfo(LogFilter.ServerLoading, "Loaded 0 ceature texts. DB table `creature_texts` is empty.");
                return;
            }

            uint textCount     = 0;
            uint creatureCount = 0;

            do
            {
                CreatureTextEntry temp = new();

                temp.creatureId      = result.Read <uint>(0);
                temp.groupId         = result.Read <byte>(1);
                temp.id              = result.Read <byte>(2);
                temp.text            = result.Read <string>(3);
                temp.type            = (ChatMsg)result.Read <byte>(4);
                temp.lang            = (Language)result.Read <byte>(5);
                temp.probability     = result.Read <float>(6);
                temp.emote           = (Emote)result.Read <uint>(7);
                temp.duration        = result.Read <uint>(8);
                temp.sound           = result.Read <uint>(9);
                temp.SoundPlayType   = (SoundKitPlayType)result.Read <byte>(10);
                temp.BroadcastTextId = result.Read <uint>(11);
                temp.TextRange       = (CreatureTextRange)result.Read <byte>(12);

                if (temp.sound != 0)
                {
                    if (!CliDB.SoundKitStorage.ContainsKey(temp.sound))
                    {
                        Log.outError(LogFilter.Sql, $"GossipManager: Entry {temp.creatureId}, Group {temp.groupId} in table `creature_texts` has Sound {temp.sound} but sound does not exist.");
                        temp.sound = 0;
                    }
                }
                if (temp.SoundPlayType >= SoundKitPlayType.Max)
                {
                    Log.outError(LogFilter.Sql, $"CreatureTextMgr: Entry {temp.creatureId}, Group {temp.groupId} in table `creature_text` has PlayType {temp.SoundPlayType} but does not exist.");
                    temp.SoundPlayType = SoundKitPlayType.Normal;
                }
                if (temp.lang != Language.Universal && !Global.LanguageMgr.IsLanguageExist(temp.lang))
                {
                    Log.outError(LogFilter.Sql, $"CreatureTextMgr: Entry {temp.creatureId}, Group {temp.groupId} in table `creature_texts` using Language {temp.lang} but Language does not exist.");
                    temp.lang = Language.Universal;
                }
                if (temp.type >= ChatMsg.Max)
                {
                    Log.outError(LogFilter.Sql, $"CreatureTextMgr: Entry {temp.creatureId}, Group {temp.groupId} in table `creature_texts` has Type {temp.type} but this Chat Type does not exist.");
                    temp.type = ChatMsg.Say;
                }
                if (temp.emote != 0)
                {
                    if (!CliDB.EmotesStorage.ContainsKey((uint)temp.emote))
                    {
                        Log.outError(LogFilter.Sql, $"CreatureTextMgr: Entry {temp.creatureId}, Group {temp.groupId} in table `creature_texts` has Emote {temp.emote} but emote does not exist.");
                        temp.emote = Emote.OneshotNone;
                    }
                }

                if (temp.BroadcastTextId != 0)
                {
                    if (!CliDB.BroadcastTextStorage.ContainsKey(temp.BroadcastTextId))
                    {
                        Log.outError(LogFilter.Sql, $"CreatureTextMgr: Entry {temp.creatureId}, Group {temp.groupId}, Id {temp.id} in table `creature_texts` has non-existing or incompatible BroadcastTextId {temp.BroadcastTextId}.");
                        temp.BroadcastTextId = 0;
                    }
                }

                if (temp.TextRange > CreatureTextRange.Personal)
                {
                    Log.outError(LogFilter.Sql, $"CreatureTextMgr: Entry {temp.creatureId}, Group {temp.groupId}, Id {temp.id} in table `creature_text` has incorrect TextRange {temp.TextRange}.");
                    temp.TextRange = CreatureTextRange.Normal;
                }

                if (!mTextMap.ContainsKey(temp.creatureId))
                {
                    mTextMap[temp.creatureId] = new MultiMap <byte, CreatureTextEntry>();
                    ++creatureCount;
                }

                mTextMap[temp.creatureId].Add(temp.groupId, temp);
                ++textCount;
            } while (result.NextRow());

            Log.outInfo(LogFilter.ServerLoading, $"Loaded {textCount} creature texts for {creatureCount} creatures in {Time.GetMSTimeDiffToNow(oldMSTime)} ms");
        }
Exemple #26
0
        void HandleChat(ChatMsg type, Language lang, string msg, string target = "")
        {
            Player sender = GetPlayer();

            if (lang == Language.Universal && type != ChatMsg.Emote)
            {
                Log.outError(LogFilter.Network, "CMSG_MESSAGECHAT: Possible hacking-attempt: {0} tried to send a message in universal language", GetPlayerInfo());
                SendNotification(CypherStrings.UnknownLanguage);
                return;
            }

            // prevent talking at unknown language (cheating)
            LanguageDesc langDesc = ObjectManager.GetLanguageDescByID(lang);

            if (langDesc == null)
            {
                SendNotification(CypherStrings.UnknownLanguage);
                return;
            }

            if (langDesc.skill_id != 0 && !sender.HasSkill((SkillType)langDesc.skill_id))
            {
                // also check SPELL_AURA_COMPREHEND_LANGUAGE (client offers option to speak in that language)
                var  langAuras = sender.GetAuraEffectsByType(AuraType.ComprehendLanguage);
                bool foundAura = false;
                foreach (var eff in langAuras)
                {
                    if (eff.GetMiscValue() == (int)lang)
                    {
                        foundAura = true;
                        break;
                    }
                }
                if (!foundAura)
                {
                    SendNotification(CypherStrings.NotLearnedLanguage);
                    return;
                }
            }

            // send in universal language if player in .gm on mode (ignore spell effects)
            if (sender.IsGameMaster())
            {
                lang = Language.Universal;
            }
            else
            {
                // send in universal language in two side iteration allowed mode
                if (HasPermission(RBACPermissions.TwoSideInteractionChat))
                {
                    lang = Language.Universal;
                }
                else
                {
                    switch (type)
                    {
                    case ChatMsg.Party:
                    case ChatMsg.Raid:
                    case ChatMsg.RaidWarning:
                        // allow two side chat at group channel if two side group allowed
                        if (WorldConfig.GetBoolValue(WorldCfg.AllowTwoSideInteractionGroup))
                        {
                            lang = Language.Universal;
                        }
                        break;

                    case ChatMsg.Guild:
                    case ChatMsg.Officer:
                        // allow two side chat at guild channel if two side guild allowed
                        if (WorldConfig.GetBoolValue(WorldCfg.AllowTwoSideInteractionGuild))
                        {
                            lang = Language.Universal;
                        }
                        break;
                    }
                }
                // but overwrite it by SPELL_AURA_MOD_LANGUAGE auras (only single case used)
                var ModLangAuras = sender.GetAuraEffectsByType(AuraType.ModLanguage);
                if (!ModLangAuras.Empty())
                {
                    lang = (Language)ModLangAuras.FirstOrDefault().GetMiscValue();
                }
            }

            if (!sender.CanSpeak())
            {
                string timeStr = Time.secsToTimeString((ulong)(m_muteTime - Time.UnixTime));
                SendNotification(CypherStrings.WaitBeforeSpeaking, timeStr);
                return;
            }

            if (sender.HasAura(1852) && type != ChatMsg.Whisper)
            {
                SendNotification(Global.ObjectMgr.GetCypherString(CypherStrings.GmSilence), sender.GetName());
                return;
            }

            if (string.IsNullOrEmpty(msg))
            {
                return;
            }

            if (new CommandHandler(this).ParseCommand(msg))
            {
                return;
            }

            switch (type)
            {
            case ChatMsg.Say:
                // Prevent cheating
                if (!sender.IsAlive())
                {
                    return;
                }

                if (sender.getLevel() < WorldConfig.GetIntValue(WorldCfg.ChatSayLevelReq))
                {
                    SendNotification(Global.ObjectMgr.GetCypherString(CypherStrings.SayReq), WorldConfig.GetIntValue(WorldCfg.ChatSayLevelReq));
                    return;
                }

                sender.Say(msg, lang);
                break;

            case ChatMsg.Emote:
                // Prevent cheating
                if (!sender.IsAlive())
                {
                    return;
                }

                if (sender.getLevel() < WorldConfig.GetIntValue(WorldCfg.ChatEmoteLevelReq))
                {
                    SendNotification(Global.ObjectMgr.GetCypherString(CypherStrings.SayReq), WorldConfig.GetIntValue(WorldCfg.ChatEmoteLevelReq));
                    return;
                }

                sender.TextEmote(msg);
                break;

            case ChatMsg.Yell:
                // Prevent cheating
                if (!sender.IsAlive())
                {
                    return;
                }

                if (sender.getLevel() < WorldConfig.GetIntValue(WorldCfg.ChatYellLevelReq))
                {
                    SendNotification(Global.ObjectMgr.GetCypherString(CypherStrings.SayReq), WorldConfig.GetIntValue(WorldCfg.ChatYellLevelReq));
                    return;
                }

                sender.Yell(msg, lang);
                break;

            case ChatMsg.Whisper:
                // @todo implement cross realm whispers (someday)
                ExtendedPlayerName extName = ObjectManager.ExtractExtendedPlayerName(target);

                if (!ObjectManager.NormalizePlayerName(ref extName.Name))
                {
                    SendChatPlayerNotfoundNotice(target);
                    break;
                }

                Player receiver = Global.ObjAccessor.FindPlayerByName(extName.Name);
                if (!receiver || (lang != Language.Addon && !receiver.isAcceptWhispers() && receiver.GetSession().HasPermission(RBACPermissions.CanFilterWhispers) && !receiver.IsInWhisperWhiteList(sender.GetGUID())))
                {
                    SendChatPlayerNotfoundNotice(target);
                    return;
                }
                if (!sender.IsGameMaster() && sender.getLevel() < WorldConfig.GetIntValue(WorldCfg.ChatWhisperLevelReq) && !receiver.IsInWhisperWhiteList(sender.GetGUID()))
                {
                    SendNotification(Global.ObjectMgr.GetCypherString(CypherStrings.WhisperReq), WorldConfig.GetIntValue(WorldCfg.ChatWhisperLevelReq));
                    return;
                }

                if (GetPlayer().GetTeam() != receiver.GetTeam() && !HasPermission(RBACPermissions.TwoSideInteractionChat) && !receiver.IsInWhisperWhiteList(sender.GetGUID()))
                {
                    SendChatPlayerNotfoundNotice(target);
                    return;
                }

                if (GetPlayer().HasAura(1852) && !receiver.IsGameMaster())
                {
                    SendNotification(Global.ObjectMgr.GetCypherString(CypherStrings.GmSilence), GetPlayer().GetName());
                    return;
                }

                if (receiver.getLevel() < WorldConfig.GetIntValue(WorldCfg.ChatWhisperLevelReq) ||
                    (HasPermission(RBACPermissions.CanFilterWhispers) && !sender.isAcceptWhispers() && !sender.IsInWhisperWhiteList(receiver.GetGUID())))
                {
                    sender.AddWhisperWhiteList(receiver.GetGUID());
                }

                GetPlayer().Whisper(msg, lang, receiver);
                break;

            case ChatMsg.Party:
            {
                // if player is in Battleground, he cannot say to Battlegroundmembers by /p
                Group group = GetPlayer().GetOriginalGroup();
                if (!group)
                {
                    group = GetPlayer().GetGroup();
                    if (!group || group.isBGGroup())
                    {
                        return;
                    }
                }

                if (group.IsLeader(GetPlayer().GetGUID()))
                {
                    type = ChatMsg.PartyLeader;
                }

                Global.ScriptMgr.OnPlayerChat(GetPlayer(), type, lang, msg, group);

                ChatPkt data = new ChatPkt();
                data.Initialize(type, lang, sender, null, msg);
                group.BroadcastPacket(data, false, group.GetMemberGroup(GetPlayer().GetGUID()));
            }
            break;

            case ChatMsg.Guild:
                if (GetPlayer().GetGuildId() != 0)
                {
                    Guild guild = Global.GuildMgr.GetGuildById(GetPlayer().GetGuildId());
                    if (guild)
                    {
                        Global.ScriptMgr.OnPlayerChat(GetPlayer(), type, lang, msg, guild);

                        guild.BroadcastToGuild(this, false, msg, lang == Language.Addon ? Language.Addon : Language.Universal);
                    }
                }
                break;

            case ChatMsg.Officer:
                if (GetPlayer().GetGuildId() != 0)
                {
                    Guild guild = Global.GuildMgr.GetGuildById(GetPlayer().GetGuildId());
                    if (guild)
                    {
                        Global.ScriptMgr.OnPlayerChat(GetPlayer(), type, lang, msg, guild);

                        guild.BroadcastToGuild(this, true, msg, lang == Language.Addon ? Language.Addon : Language.Universal);
                    }
                }
                break;

            case ChatMsg.Raid:
            {
                Group group = GetPlayer().GetGroup();
                if (!group || !group.isRaidGroup() || group.isBGGroup())
                {
                    return;
                }

                if (group.IsLeader(GetPlayer().GetGUID()))
                {
                    type = ChatMsg.RaidLeader;
                }

                Global.ScriptMgr.OnPlayerChat(GetPlayer(), type, lang, msg, group);

                ChatPkt data = new ChatPkt();
                data.Initialize(type, lang, sender, null, msg);
                group.BroadcastPacket(data, false);
            }
            break;

            case ChatMsg.RaidWarning:
            {
                Group group = GetPlayer().GetGroup();
                if (!group || !group.isRaidGroup() || !(group.IsLeader(GetPlayer().GetGUID()) || group.IsAssistant(GetPlayer().GetGUID())) || group.isBGGroup())
                {
                    return;
                }

                Global.ScriptMgr.OnPlayerChat(GetPlayer(), type, lang, msg, group);

                ChatPkt data = new ChatPkt();
                //in Battleground, raid warning is sent only to players in Battleground - code is ok
                data.Initialize(ChatMsg.RaidWarning, lang, sender, null, msg);
                group.BroadcastPacket(data, false);
            }
            break;

            case ChatMsg.Channel:
                if (!HasPermission(RBACPermissions.SkipCheckChatChannelReq))
                {
                    if (GetPlayer().getLevel() < WorldConfig.GetIntValue(WorldCfg.ChatChannelLevelReq))
                    {
                        SendNotification(Global.ObjectMgr.GetCypherString(CypherStrings.ChannelReq), WorldConfig.GetIntValue(WorldCfg.ChatChannelLevelReq));
                        return;
                    }
                }
                Channel chn = ChannelManager.GetChannelForPlayerByNamePart(target, sender);
                if (chn != null)
                {
                    Global.ScriptMgr.OnPlayerChat(GetPlayer(), type, lang, msg, chn);
                    chn.Say(GetPlayer().GetGUID(), msg, lang);
                }
                break;

            case ChatMsg.InstanceChat:
            {
                Group group = GetPlayer().GetGroup();
                if (!group)
                {
                    return;
                }

                if (group.IsLeader(GetPlayer().GetGUID()))
                {
                    type = ChatMsg.InstanceChatLeader;
                }

                Global.ScriptMgr.OnPlayerChat(GetPlayer(), type, lang, msg, group);

                ChatPkt packet = new ChatPkt();
                packet.Initialize(type, lang, sender, null, msg);
                group.BroadcastPacket(packet, false);
                break;
            }

            default:
                Log.outError(LogFilter.ChatSystem, "CHAT: unknown message type {0}, lang: {1}", type, lang);
                break;
            }
        }
Exemple #27
0
        void HandleOpenItem(OpenItem packet)
        {
            Player player = GetPlayer();

            // ignore for remote control state
            if (player.m_unitMovedByMe != player)
            {
                return;
            }

            Item item = player.GetItemByPos(packet.Slot, packet.PackSlot);

            if (!item)
            {
                player.SendEquipError(InventoryResult.ItemNotFound);
                return;
            }

            ItemTemplate proto = item.GetTemplate();

            if (proto == null)
            {
                player.SendEquipError(InventoryResult.ItemNotFound, item);
                return;
            }

            // Verify that the bag is an actual bag or wrapped item that can be used "normally"
            if (!proto.GetFlags().HasAnyFlag(ItemFlags.HasLoot) && !item.HasFlag(ItemFields.Flags, ItemFieldFlags.Wrapped))
            {
                player.SendEquipError(InventoryResult.ClientLockedOut, item);
                Log.outError(LogFilter.Network, "Possible hacking attempt: Player {0} [guid: {1}] tried to open item [guid: {2}, entry: {3}] which is not openable!",
                             player.GetName(), player.GetGUID().ToString(), item.GetGUID().ToString(), proto.GetId());
                return;
            }

            // locked item
            uint lockId = proto.GetLockID();

            if (lockId != 0)
            {
                LockRecord lockInfo = CliDB.LockStorage.LookupByKey(lockId);
                if (lockInfo == null)
                {
                    player.SendEquipError(InventoryResult.ItemLocked, item);
                    Log.outError(LogFilter.Network, "WORLD:OpenItem: item [guid = {0}] has an unknown lockId: {1}!", item.GetGUID().ToString(), lockId);
                    return;
                }

                // was not unlocked yet
                if (item.IsLocked())
                {
                    player.SendEquipError(InventoryResult.ItemLocked, item);
                    return;
                }
            }

            if (item.HasFlag(ItemFields.Flags, ItemFieldFlags.Wrapped))// wrapped?
            {
                PreparedStatement stmt = DB.Characters.GetPreparedStatement(CharStatements.SEL_CHARACTER_GIFT_BY_ITEM);
                stmt.AddValue(0, item.GetGUID().GetCounter());
                SQLResult result = DB.Characters.Query(stmt);

                if (!result.IsEmpty())
                {
                    uint entry = result.Read <uint>(0);
                    uint flags = result.Read <uint>(1);

                    item.SetUInt64Value(ItemFields.GiftCreator, 0);
                    item.SetEntry(entry);
                    item.SetUInt32Value(ItemFields.Flags, flags);
                    item.SetState(ItemUpdateState.Changed, player);
                }
                else
                {
                    Log.outError(LogFilter.Network, "Wrapped item {0} don't have record in character_gifts table and will deleted", item.GetGUID().ToString());
                    player.DestroyItem(item.GetBagSlot(), item.GetSlot(), true);
                    return;
                }

                stmt = DB.Characters.GetPreparedStatement(CharStatements.DEL_GIFT);
                stmt.AddValue(0, item.GetGUID().GetCounter());
                DB.Characters.Execute(stmt);
            }
            else
            {
                player.SendLoot(item.GetGUID(), LootType.Corpse);
            }
        }
Exemple #28
0
        void HandleChatAddon(ChatMsg type, string prefix, string text, string target = "")
        {
            Player sender = GetPlayer();

            if (string.IsNullOrEmpty(prefix) || prefix.Length > 16)
            {
                return;
            }

            // Disabled addon channel?
            if (!WorldConfig.GetBoolValue(WorldCfg.AddonChannel))
            {
                return;
            }

            switch (type)
            {
            case ChatMsg.Guild:
            case ChatMsg.Officer:
                if (sender.GetGuildId() != 0)
                {
                    Guild guild = Global.GuildMgr.GetGuildById(sender.GetGuildId());
                    if (guild)
                    {
                        guild.BroadcastAddonToGuild(this, type == ChatMsg.Officer, text, prefix);
                    }
                }
                break;

            case ChatMsg.Whisper:
                // @todo implement cross realm whispers (someday)
                ExtendedPlayerName extName = ObjectManager.ExtractExtendedPlayerName(target);

                if (!ObjectManager.NormalizePlayerName(ref extName.Name))
                {
                    break;
                }

                Player receiver = Global.ObjAccessor.FindPlayerByName(extName.Name);
                if (!receiver)
                {
                    break;
                }

                sender.WhisperAddon(text, prefix, receiver);
                break;

            // Messages sent to "RAID" while in a party will get delivered to "PARTY"
            case ChatMsg.Party:
            case ChatMsg.Raid:
            case ChatMsg.InstanceChat:
            {
                Group group    = null;
                int   subGroup = -1;
                if (type != ChatMsg.InstanceChat)
                {
                    group = sender.GetOriginalGroup();
                }

                if (!group)
                {
                    group = sender.GetGroup();
                    if (!group)
                    {
                        break;
                    }

                    if (type == ChatMsg.Party)
                    {
                        subGroup = sender.GetSubGroup();
                    }
                }

                ChatPkt data = new ChatPkt();
                data.Initialize(type, Language.Addon, sender, null, text, 0, "", LocaleConstant.enUS, prefix);
                group.BroadcastAddonMessagePacket(data, prefix, true, subGroup, sender.GetGUID());
                break;
            }

            case ChatMsg.Channel:
                Channel chn = ChannelManager.GetChannelForPlayerByNamePart(target, sender);
                if (chn != null)
                {
                    chn.AddonSay(sender.GetGUID(), prefix, text);
                }
                break;

            default:
                Log.outError(LogFilter.Server, "HandleAddonMessagechat: unknown addon message type {0}", type);
                break;
            }
        }
Exemple #29
0
        public void LoadDisables()
        {
            uint oldMSTime = Time.GetMSTime();

            // reload case
            m_DisableMap.Clear();

            SQLResult result = DB.World.Query("SELECT sourceType, entry, flags, params_0, params_1 FROM disables");

            if (result.IsEmpty())
            {
                Log.outError(LogFilter.ServerLoading, "Loaded 0 disables. DB table `disables` is empty!");
                return;
            }

            uint total_count = 0;

            do
            {
                DisableType type = (DisableType)result.Read <uint>(0);
                if (type >= DisableType.Max)
                {
                    Log.outError(LogFilter.Sql, "Invalid type {0} specified in `disables` table, skipped.", type);
                    continue;
                }

                uint   entry    = result.Read <uint>(1);
                byte   flags    = result.Read <byte>(2);
                string params_0 = result.Read <string>(3);
                string params_1 = result.Read <string>(4);

                DisableData data = new DisableData();
                data.flags = flags;

                switch (type)
                {
                case DisableType.Spell:
                    if (!(Global.SpellMgr.HasSpellInfo(entry) || flags.HasAnyFlag <byte>(DisableFlags.SpellDeprecatedSpell)))
                    {
                        Log.outError(LogFilter.Sql, "Spell entry {0} from `disables` doesn't exist in dbc, skipped.", entry);
                        continue;
                    }

                    if (flags == 0 || flags > DisableFlags.MaxSpell)
                    {
                        Log.outError(LogFilter.Sql, "Disable flags for spell {0} are invalid, skipped.", entry);
                        continue;
                    }

                    if (flags.HasAnyFlag(DisableFlags.SpellMap))
                    {
                        var array = new StringArray(params_0, ',');
                        for (byte i = 0; i < array.Length;)
                        {
                            if (uint.TryParse(array[i++], out uint id))
                            {
                                data.param0.Add(id);
                            }
                        }
                    }

                    if (flags.HasAnyFlag(DisableFlags.SpellArea))
                    {
                        var array = new StringArray(params_1, ',');
                        for (byte i = 0; i < array.Length;)
                        {
                            if (uint.TryParse(array[i++], out uint id))
                            {
                                data.param1.Add(id);
                            }
                        }
                    }

                    break;

                // checked later
                case DisableType.Quest:
                    break;

                case DisableType.Map:
                case DisableType.LFGMap:
                {
                    MapRecord mapEntry = CliDB.MapStorage.LookupByKey(entry);
                    if (mapEntry == null)
                    {
                        Log.outError(LogFilter.Sql, "Map entry {0} from `disables` doesn't exist in dbc, skipped.", entry);
                        continue;
                    }
                    bool isFlagInvalid = false;
                    switch (mapEntry.InstanceType)
                    {
                    case MapTypes.Common:
                        if (flags != 0)
                        {
                            isFlagInvalid = true;
                        }
                        break;

                    case MapTypes.Instance:
                    case MapTypes.Raid:
                        if (flags.HasAnyFlag(DisableFlags.DungeonStatusHeroic) && Global.DB2Mgr.GetMapDifficultyData(entry, Difficulty.Heroic) == null)
                        {
                            flags -= DisableFlags.DungeonStatusHeroic;
                        }
                        if (flags.HasAnyFlag(DisableFlags.DungeonStatusHeroic10Man) && Global.DB2Mgr.GetMapDifficultyData(entry, Difficulty.Raid10HC) == null)
                        {
                            flags -= DisableFlags.DungeonStatusHeroic10Man;
                        }
                        if (flags.HasAnyFlag(DisableFlags.DungeonStatusHeroic25Man) && Global.DB2Mgr.GetMapDifficultyData(entry, Difficulty.Raid25HC) == null)
                        {
                            flags -= DisableFlags.DungeonStatusHeroic25Man;
                        }
                        if (flags == 0)
                        {
                            isFlagInvalid = true;
                        }
                        break;

                    case MapTypes.Battleground:
                    case MapTypes.Arena:
                        Log.outError(LogFilter.Sql, "Battlegroundmap {0} specified to be disabled in map case, skipped.", entry);
                        continue;
                    }
                    if (isFlagInvalid)
                    {
                        Log.outError(LogFilter.Sql, "Disable flags for map {0} are invalid, skipped.", entry);
                        continue;
                    }
                    break;
                }

                case DisableType.Battleground:
                    if (!CliDB.BattlemasterListStorage.ContainsKey(entry))
                    {
                        Log.outError(LogFilter.Sql, "Battlegroundentry {0} from `disables` doesn't exist in dbc, skipped.", entry);
                        continue;
                    }
                    if (flags != 0)
                    {
                        Log.outError(LogFilter.Sql, "Disable flags specified for Battleground{0}, useless data.", entry);
                    }
                    break;

                case DisableType.OutdoorPVP:
                    if (entry > (int)OutdoorPvPTypes.Max)
                    {
                        Log.outError(LogFilter.Sql, "OutdoorPvPTypes value {0} from `disables` is invalid, skipped.", entry);
                        continue;
                    }
                    if (flags != 0)
                    {
                        Log.outError(LogFilter.Sql, "Disable flags specified for outdoor PvP {0}, useless data.", entry);
                    }
                    break;

                case DisableType.Criteria:
                    if (Global.CriteriaMgr.GetCriteria(entry) == null)
                    {
                        Log.outError(LogFilter.Sql, "Criteria entry {0} from `disables` doesn't exist in dbc, skipped.", entry);
                        continue;
                    }
                    if (flags != 0)
                    {
                        Log.outError(LogFilter.Sql, "Disable flags specified for Criteria {0}, useless data.", entry);
                    }
                    break;

                case DisableType.VMAP:
                {
                    MapRecord mapEntry = CliDB.MapStorage.LookupByKey(entry);
                    if (mapEntry == null)
                    {
                        Log.outError(LogFilter.Sql, "Map entry {0} from `disables` doesn't exist in dbc, skipped.", entry);
                        continue;
                    }
                    switch (mapEntry.InstanceType)
                    {
                    case MapTypes.Common:
                        if (flags.HasAnyFlag(DisableFlags.VmapAreaFlag))
                        {
                            Log.outInfo(LogFilter.Server, "Areaflag disabled for world map {0}.", entry);
                        }
                        if (flags.HasAnyFlag(DisableFlags.VmapLiquidStatus))
                        {
                            Log.outInfo(LogFilter.Server, "Liquid status disabled for world map {0}.", entry);
                        }
                        break;

                    case MapTypes.Instance:
                    case MapTypes.Raid:
                        if (flags.HasAnyFlag(DisableFlags.VmapHeight))
                        {
                            Log.outInfo(LogFilter.Server, "Height disabled for instance map {0}.", entry);
                        }
                        if (flags.HasAnyFlag(DisableFlags.VmapLOS))
                        {
                            Log.outInfo(LogFilter.Server, "LoS disabled for instance map {0}.", entry);
                        }
                        break;

                    case MapTypes.Battleground:
                        if (flags.HasAnyFlag(DisableFlags.VmapHeight))
                        {
                            Log.outInfo(LogFilter.Server, "Height disabled for Battlegroundmap {0}.", entry);
                        }
                        if (flags.HasAnyFlag(DisableFlags.VmapLOS))
                        {
                            Log.outInfo(LogFilter.Server, "LoS disabled for Battlegroundmap {0}.", entry);
                        }
                        break;

                    case MapTypes.Arena:
                        if (flags.HasAnyFlag(DisableFlags.VmapHeight))
                        {
                            Log.outInfo(LogFilter.Server, "Height disabled for arena map {0}.", entry);
                        }
                        if (flags.HasAnyFlag(DisableFlags.VmapLOS))
                        {
                            Log.outInfo(LogFilter.Server, "LoS disabled for arena map {0}.", entry);
                        }
                        break;

                    default:
                        break;
                    }
                    break;
                }

                case DisableType.MMAP:
                {
                    MapRecord mapEntry = CliDB.MapStorage.LookupByKey(entry);
                    if (mapEntry == null)
                    {
                        Log.outError(LogFilter.Sql, "Map entry {0} from `disables` doesn't exist in dbc, skipped.", entry);
                        continue;
                    }
                    switch (mapEntry.InstanceType)
                    {
                    case MapTypes.Common:
                        Log.outInfo(LogFilter.Server, "Pathfinding disabled for world map {0}.", entry);
                        break;

                    case MapTypes.Instance:
                    case MapTypes.Raid:
                        Log.outInfo(LogFilter.Server, "Pathfinding disabled for instance map {0}.", entry);
                        break;

                    case MapTypes.Battleground:
                        Log.outInfo(LogFilter.Server, "Pathfinding disabled for Battlegroundmap {0}.", entry);
                        break;

                    case MapTypes.Arena:
                        Log.outInfo(LogFilter.Server, "Pathfinding disabled for arena map {0}.", entry);
                        break;

                    default:
                        break;
                    }
                    break;
                }

                default:
                    break;
                }
                if (!m_DisableMap.ContainsKey(type))
                {
                    m_DisableMap[type] = new Dictionary <uint, DisableData>();
                }

                m_DisableMap[type].Add(entry, data);
                ++total_count;
            }while (result.NextRow());

            Log.outInfo(LogFilter.ServerLoading, "Loaded {0} disables in {1} ms", total_count, Time.GetMSTimeDiffToNow(oldMSTime));
        }
Exemple #30
0
        void HandlePetAction(PetAction packet)
        {
            ObjectGuid guid1 = packet.PetGUID;         //pet guid
            ObjectGuid guid2 = packet.TargetGUID;      //tag guid

            uint         spellid = UnitActionBarEntry.UNIT_ACTION_BUTTON_ACTION(packet.Action);
            ActiveStates flag    = (ActiveStates)UnitActionBarEntry.UNIT_ACTION_BUTTON_TYPE(packet.Action);          //delete = 0x07 CastSpell = C1

            // used also for charmed creature
            Unit pet = Global.ObjAccessor.GetUnit(GetPlayer(), guid1);

            if (!pet)
            {
                Log.outError(LogFilter.Network, "HandlePetAction: {0} doesn't exist for {1}", guid1.ToString(), GetPlayer().GetGUID().ToString());
                return;
            }

            if (pet != GetPlayer().GetFirstControlled())
            {
                Log.outError(LogFilter.Network, "HandlePetAction: {0} does not belong to {1}", guid1.ToString(), GetPlayer().GetGUID().ToString());
                return;
            }

            if (!pet.IsAlive())
            {
                SpellInfo spell = (flag == ActiveStates.Enabled || flag == ActiveStates.Passive) ? Global.SpellMgr.GetSpellInfo(spellid, pet.GetMap().GetDifficultyID()) : null;
                if (spell == null)
                {
                    return;
                }
                if (!spell.HasAttribute(SpellAttr0.CastableWhileDead))
                {
                    return;
                }
            }

            // @todo allow control charmed player?
            if (pet.IsTypeId(TypeId.Player) && !(flag == ActiveStates.Command && spellid == (uint)CommandStates.Attack))
            {
                return;
            }

            if (GetPlayer().m_Controlled.Count == 1)
            {
                HandlePetActionHelper(pet, guid1, spellid, flag, guid2, packet.ActionPosition.X, packet.ActionPosition.Y, packet.ActionPosition.Z);
            }
            else
            {
                //If a pet is dismissed, m_Controlled will change
                List <Unit> controlled = new();
                foreach (var unit in GetPlayer().m_Controlled)
                {
                    if (unit.GetEntry() == pet.GetEntry() && unit.IsAlive())
                    {
                        controlled.Add(unit);
                    }
                }

                foreach (var unit in controlled)
                {
                    HandlePetActionHelper(unit, guid1, spellid, flag, guid2, packet.ActionPosition.X, packet.ActionPosition.Y, packet.ActionPosition.Z);
                }
            }
        }