Example #1
0
        public bool IsDisabledFor(DisableType type, uint entry, Unit unit, byte flags = 0)
        {
            Cypher.Assert(type < DisableType.Max);
            if (!m_DisableMap.ContainsKey(type) || m_DisableMap[type].Empty())
            {
                return(false);
            }

            var data = m_DisableMap[type].LookupByKey(entry);

            if (data == null)    // not disabled
            {
                return(false);
            }

            switch (type)
            {
            case DisableType.Spell:
            {
                byte spellFlags = data.flags;
                if (unit != null)
                {
                    if ((spellFlags.HasAnyFlag(DisableFlags.SpellPlayer) && unit.IsTypeId(TypeId.Player)) ||
                        (unit.IsTypeId(TypeId.Unit) && ((unit.IsPet() && spellFlags.HasAnyFlag(DisableFlags.SpellPet)) || spellFlags.HasAnyFlag(DisableFlags.SpellCreature))))
                    {
                        if (spellFlags.HasAnyFlag(DisableFlags.SpellMap))
                        {
                            List <uint> mapIds = data.param0;
                            if (mapIds.Contains(unit.GetMapId()))
                            {
                                return(true);                                               // Spell is disabled on current map
                            }
                            if (!spellFlags.HasAnyFlag(DisableFlags.SpellArea))
                            {
                                return(false);                                              // Spell is disabled on another map, but not this one, return false
                            }
                            // Spell is disabled in an area, but not explicitly our current mapId. Continue processing.
                        }

                        if (spellFlags.HasAnyFlag(DisableFlags.SpellArea))
                        {
                            var areaIds = data.param1;
                            if (areaIds.Contains(unit.GetAreaId()))
                            {
                                return(true);                                               // Spell is disabled in this area
                            }
                            return(false);                                                  // Spell is disabled in another area, but not this one, return false
                        }
                        else
                        {
                            return(true);                                                   // Spell disabled for all maps
                        }
                    }

                    return(false);
                }
                else if (spellFlags.HasAnyFlag(DisableFlags.SpellDeprecatedSpell))            // call not from spellcast
                {
                    return(true);
                }
                else if (flags.HasAnyFlag(DisableFlags.SpellLOS))
                {
                    return(spellFlags.HasAnyFlag(DisableFlags.SpellLOS));
                }

                break;
            }

            case DisableType.Map:
            case DisableType.LFGMap:
                Player player = unit.ToPlayer();
                if (player != null)
                {
                    MapRecord mapEntry = CliDB.MapStorage.LookupByKey(entry);
                    if (mapEntry.IsDungeon())
                    {
                        byte       disabledModes    = data.flags;
                        Difficulty targetDifficulty = player.GetDifficultyID(mapEntry);
                        Global.DB2Mgr.GetDownscaledMapDifficultyData(entry, ref targetDifficulty);
                        switch (targetDifficulty)
                        {
                        case Difficulty.Normal:
                            return(disabledModes.HasAnyFlag(DisableFlags.DungeonStatusNormal));

                        case Difficulty.Heroic:
                            return(disabledModes.HasAnyFlag(DisableFlags.DungeonStatusHeroic));

                        case Difficulty.Raid10HC:
                            return(disabledModes.HasAnyFlag(DisableFlags.DungeonStatusHeroic10Man));

                        case Difficulty.Raid25HC:
                            return(disabledModes.HasAnyFlag(DisableFlags.DungeonStatusHeroic25Man));

                        default:
                            return(false);
                        }
                    }
                    else if (mapEntry.InstanceType == MapTypes.Common)
                    {
                        return(true);
                    }
                }
                return(false);

            case DisableType.Quest:
                if (unit == null)
                {
                    return(true);
                }
                Player player1 = unit.ToPlayer();
                if (player1 != null)
                {
                    if (player1.IsGameMaster())
                    {
                        return(false);
                    }
                }
                return(true);

            case DisableType.Battleground:
            case DisableType.OutdoorPVP:
            case DisableType.Criteria:
            case DisableType.MMAP:
                return(true);

            case DisableType.VMAP:
                return(flags.HasAnyFlag(data.flags));
            }

            return(false);
        }
Example #2
0
        public void LoadGroups()
        {
            {
                uint oldMSTime = Time.GetMSTime();

                // Delete all groups whose leader does not exist
                DB.Characters.Execute("DELETE FROM groups WHERE leaderGuid NOT IN (SELECT guid FROM characters)");
                // Delete all groups with less than 2 members
                DB.Characters.Execute("DELETE FROM groups WHERE guid NOT IN (SELECT guid FROM group_member GROUP BY guid HAVING COUNT(guid) > 1)");

                //                                                    0              1           2             3                 4      5          6      7         8       9
                SQLResult result = DB.Characters.Query("SELECT g.leaderGuid, g.lootMethod, g.looterGuid, g.lootThreshold, g.icon1, g.icon2, g.icon3, g.icon4, g.icon5, g.icon6" +
                                                       //  10         11          12         13              14                  15                     16             17          18         19
                                                       ", g.icon7, g.icon8, g.groupType, g.difficulty, g.raiddifficulty, g.legacyRaidDifficulty, g.masterLooterGuid, g.guid, lfg.dungeon, lfg.state FROM groups g LEFT JOIN lfg_data lfg ON lfg.guid = g.guid ORDER BY g.guid ASC");
                if (result.IsEmpty())
                {
                    Log.outInfo(LogFilter.ServerLoading, "Loaded 0 group definitions. DB table `groups` is empty!");
                    return;
                }

                uint count = 0;
                do
                {
                    Group group = new Group();
                    group.LoadGroupFromDB(result.GetFields());
                    AddGroup(group);

                    // Get the ID used for storing the group in the database and register it in the pool.
                    uint storageId = group.GetDbStoreId();

                    RegisterGroupDbStoreId(storageId, group);

                    // Increase the next available storage ID
                    if (storageId == NextGroupDbStoreId)
                    {
                        NextGroupDbStoreId++;
                    }

                    ++count;
                }while (result.NextRow());

                Log.outInfo(LogFilter.ServerLoading, "Loaded {0} group definitions in {1} ms", count, Time.GetMSTimeDiffToNow(oldMSTime));
            }

            Log.outInfo(LogFilter.ServerLoading, "Loading Group members...");
            {
                uint oldMSTime = Time.GetMSTime();

                // Delete all rows from group_member or group_instance with no group
                DB.Characters.Execute("DELETE FROM group_member WHERE guid NOT IN (SELECT guid FROM groups)");
                DB.Characters.Execute("DELETE FROM group_instance WHERE guid NOT IN (SELECT guid FROM groups)");
                // Delete all members that does not exist
                DB.Characters.Execute("DELETE FROM group_member WHERE memberGuid NOT IN (SELECT guid FROM characters)");

                //                                                0        1           2            3       4
                SQLResult result = DB.Characters.Query("SELECT guid, memberGuid, memberFlags, subgroup, roles FROM group_member ORDER BY guid");
                if (result.IsEmpty())
                {
                    Log.outInfo(LogFilter.ServerLoading, "Loaded 0 group members. DB table `group_member` is empty!");
                    return;
                }

                uint count = 0;

                do
                {
                    Group group = GetGroupByDbStoreId(result.Read <uint>(0));

                    if (group)
                    {
                        group.LoadMemberFromDB(result.Read <uint>(1), result.Read <byte>(2), result.Read <byte>(3), (LfgRoles)result.Read <byte>(4));
                    }
                    else
                    {
                        Log.outError(LogFilter.Server, "GroupMgr:LoadGroups: Consistency failed, can't find group (storage id: {0})", result.Read <uint>(0));
                    }

                    ++count;
                }while (result.NextRow());

                Log.outInfo(LogFilter.ServerLoading, "Loaded {0} group members in {1} ms", count, Time.GetMSTimeDiffToNow(oldMSTime));
            }

            Log.outInfo(LogFilter.ServerLoading, "Loading Group instance saves...");
            {
                uint oldMSTime = Time.GetMSTime();
                //                                                0           1        2              3             4             5            6           7
                SQLResult result = DB.Characters.Query("SELECT gi.guid, i.map, gi.instance, gi.permanent, i.difficulty, i.resettime, i.entranceId, COUNT(g.guid) " +
                                                       "FROM group_instance gi INNER JOIN instance i ON gi.instance = i.id " +
                                                       "LEFT JOIN character_instance ci LEFT JOIN groups g ON g.leaderGuid = ci.guid ON ci.instance = gi.instance AND ci.permanent = 1 GROUP BY gi.instance ORDER BY gi.guid");
                if (result.IsEmpty())
                {
                    Log.outInfo(LogFilter.ServerLoading, "Loaded 0 group-instance saves. DB table `group_instance` is empty!");
                    return;
                }

                uint count = 0;
                do
                {
                    Group group = GetGroupByDbStoreId(result.Read <uint>(0));
                    // group will never be NULL (we have run consistency sql's before loading)

                    MapRecord mapEntry = CliDB.MapStorage.LookupByKey(result.Read <ushort>(1));
                    if (mapEntry == null || !mapEntry.IsDungeon())
                    {
                        Log.outError(LogFilter.Sql, "Incorrect entry in group_instance table : no dungeon map {0}", result.Read <ushort>(1));
                        continue;
                    }

                    uint             diff            = result.Read <byte>(4);
                    DifficultyRecord difficultyEntry = CliDB.DifficultyStorage.LookupByKey(diff);
                    if (difficultyEntry == null || difficultyEntry.InstanceType != mapEntry.InstanceType)
                    {
                        continue;
                    }

                    InstanceSave save = Global.InstanceSaveMgr.AddInstanceSave(mapEntry.Id, result.Read <uint>(2), (Difficulty)diff, result.Read <uint>(5), result.Read <uint>(6), result.Read <ulong>(7) != 0, true);
                    group.BindToInstance(save, result.Read <bool>(3), true);
                    ++count;
                }while (result.NextRow());

                Log.outInfo(LogFilter.ServerLoading, "Loaded {0} group-instance saves in {1} ms", count, Time.GetMSTimeDiffToNow(oldMSTime));
            }
        }
Example #3
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();

            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
                        FlightPathMovementGenerator flight = (FlightPathMovementGenerator)GetPlayer().GetMotionMaster().Top();
                        flight.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();
        }
Example #4
0
        public EnterState PlayerCannotEnter(uint mapid, Player player, bool loginCheck = false)
        {
            MapRecord entry = CliDB.MapStorage.LookupByKey(mapid);

            if (entry == null)
            {
                return(EnterState.CannotEnterNoEntry);
            }

            if (!entry.IsDungeon())
            {
                return(EnterState.CanEnter);
            }

            InstanceTemplate instance = Global.ObjectMgr.GetInstanceTemplate(mapid);

            if (instance == null)
            {
                return(EnterState.CannotEnterUninstancedDungeon);
            }

            Difficulty targetDifficulty = player.GetDifficultyID(entry);
            // Get the highest available difficulty if current setting is higher than the instance allows
            MapDifficultyRecord mapDiff = Global.DB2Mgr.GetDownscaledMapDifficultyData(entry.Id, ref targetDifficulty);

            if (mapDiff == null)
            {
                return(EnterState.CannotEnterDifficultyUnavailable);
            }

            //Bypass checks for GMs
            if (player.IsGameMaster())
            {
                return(EnterState.CanEnter);
            }

            string mapName = entry.MapName[Global.WorldMgr.GetDefaultDbcLocale()];

            Group group = player.GetGroup();

            if (entry.IsRaid() && entry.Expansion() >= (Expansion)WorldConfig.GetIntValue(WorldCfg.Expansion)) // can only enter in a raid group but raids from old expansion don't need a group
            {
                if ((!group || !group.isRaidGroup()) && WorldConfig.GetBoolValue(WorldCfg.InstanceIgnoreRaid))
                {
                    return(EnterState.CannotEnterNotInRaid);
                }
            }

            if (!player.IsAlive())
            {
                if (player.HasCorpse())
                {
                    // let enter in ghost mode in instance that connected to inner instance with corpse
                    uint corpseMap = player.GetCorpseLocation().GetMapId();
                    do
                    {
                        if (corpseMap == mapid)
                        {
                            break;
                        }

                        InstanceTemplate corpseInstance = Global.ObjectMgr.GetInstanceTemplate(corpseMap);
                        corpseMap = corpseInstance != null ? corpseInstance.Parent : 0;
                    } while (corpseMap != 0);

                    if (corpseMap == 0)
                    {
                        return(EnterState.CannotEnterCorpseInDifferentInstance);
                    }

                    Log.outDebug(LogFilter.Maps, "MAP: Player '{0}' has corpse in instance '{1}' and can enter.", player.GetName(), mapName);
                }
                else
                {
                    Log.outDebug(LogFilter.Maps, "Map.CanPlayerEnter - player '{0}' is dead but does not have a corpse!", player.GetName());
                }
            }

            //Get instance where player's group is bound & its map
            if (!loginCheck && group)
            {
                InstanceBind boundInstance = group.GetBoundInstance(entry);
                if (boundInstance != null && boundInstance.save != null)
                {
                    Map boundMap = FindMap(mapid, boundInstance.save.GetInstanceId());
                    if (boundMap != null)
                    {
                        EnterState denyReason = boundMap.CannotEnter(player);
                        if (denyReason != 0)
                        {
                            return(denyReason);
                        }
                    }
                }
            }
            // players are only allowed to enter 10 instances per hour
            if (entry.IsDungeon() && (player.GetGroup() == null || (player.GetGroup() != null && !player.GetGroup().isLFGGroup())))
            {
                uint         instaceIdToCheck = 0;
                InstanceSave save             = player.GetInstanceSave(mapid);
                if (save != null)
                {
                    instaceIdToCheck = save.GetInstanceId();
                }

                // instanceId can never be 0 - will not be found
                if (!player.CheckInstanceCount(instaceIdToCheck) && !player.IsDead())
                {
                    return(EnterState.CannotEnterTooManyInstances);
                }
            }

            //Other requirements
            if (player.Satisfy(Global.ObjectMgr.GetAccessRequirement(mapid, targetDifficulty), mapid, true))
            {
                return(EnterState.CanEnter);
            }
            else
            {
                return(EnterState.CannotEnterUnspecifiedReason);
            }
        }