Пример #1
0
        public void SendRaidInfo()
        {
            InstanceInfoPkt instanceInfo = new InstanceInfoPkt();

            long now = Time.UnixTime;

            for (byte i = 0; i < (int)Difficulty.Max; ++i)
            {
                foreach (var pair in m_boundInstances[i])
                {
                    InstanceBind bind = pair.Value;
                    if (bind.perm)
                    {
                        InstanceSave save = pair.Value.save;

                        InstanceLockInfos lockInfos;

                        lockInfos.InstanceID   = save.GetInstanceId();
                        lockInfos.MapID        = save.GetMapId();
                        lockInfos.DifficultyID = (uint)save.GetDifficultyID();
                        if (bind.extendState != BindExtensionState.Extended)
                        {
                            lockInfos.TimeRemaining = (int)(save.GetResetTime() - now);
                        }
                        else
                        {
                            lockInfos.TimeRemaining = (int)(Global.InstanceSaveMgr.GetSubsequentResetTime(save.GetMapId(), save.GetDifficultyID(), save.GetResetTime()) - now);
                        }

                        lockInfos.CompletedMask = 0;
                        Map map = Global.MapMgr.FindMap(save.GetMapId(), save.GetInstanceId());
                        if (map != null)
                        {
                            InstanceScript instanceScript = ((InstanceMap)map).GetInstanceScript();
                            if (instanceScript != null)
                            {
                                lockInfos.CompletedMask = instanceScript.GetCompletedEncounterMask();
                            }
                        }

                        lockInfos.Locked   = bind.extendState != BindExtensionState.Expired;
                        lockInfos.Extended = bind.extendState == BindExtensionState.Extended;

                        instanceInfo.LockList.Add(lockInfos);
                    }
                }
            }

            SendPacket(instanceInfo);
        }
Пример #2
0
        public void SendRaidInfo()
        {
            InstanceInfoPkt instanceInfo = new();

            long now = GameTime.GetGameTime();

            foreach (var difficultyDic in m_boundInstances.Values)
            {
                foreach (var instanceBind in difficultyDic.Values)
                {
                    if (instanceBind.perm)
                    {
                        InstanceSave save = instanceBind.save;

                        InstanceLock lockInfos;
                        lockInfos.InstanceID   = save.GetInstanceId();
                        lockInfos.MapID        = save.GetMapId();
                        lockInfos.DifficultyID = (uint)save.GetDifficultyID();
                        if (instanceBind.extendState != BindExtensionState.Extended)
                        {
                            lockInfos.TimeRemaining = (int)(save.GetResetTime() - now);
                        }
                        else
                        {
                            lockInfos.TimeRemaining = (int)(Global.InstanceSaveMgr.GetSubsequentResetTime(save.GetMapId(), save.GetDifficultyID(), save.GetResetTime()) - now);
                        }

                        lockInfos.CompletedMask = 0;
                        Map map = Global.MapMgr.FindMap(save.GetMapId(), save.GetInstanceId());
                        if (map != null)
                        {
                            InstanceScript instanceScript = ((InstanceMap)map).GetInstanceScript();
                            if (instanceScript != null)
                            {
                                lockInfos.CompletedMask = instanceScript.GetCompletedEncounterMask();
                            }
                        }

                        lockInfos.Locked   = instanceBind.extendState != BindExtensionState.Expired;
                        lockInfos.Extended = instanceBind.extendState == BindExtensionState.Extended;

                        instanceInfo.LockList.Add(lockInfos);
                    }
                }
            }

            SendPacket(instanceInfo);
        }
Пример #3
0
        // Reset all solo instances and optionally send a message on success for each
        public void ResetInstances(InstanceResetMethod method, bool isRaid, bool isLegacy)
        {
            // method can be INSTANCE_RESET_ALL, INSTANCE_RESET_CHANGE_DIFFICULTY, INSTANCE_RESET_GROUP_JOIN

            // we assume that when the difficulty changes, all instances that can be reset will be
            Difficulty diff = GetDungeonDifficultyID();

            if (isRaid)
            {
                if (!isLegacy)
                {
                    diff = GetRaidDifficultyID();
                }
                else
                {
                    diff = GetLegacyRaidDifficultyID();
                }
            }

            foreach (var pair in m_boundInstances[(int)diff].ToList())
            {
                InstanceSave p     = pair.Value.save;
                MapRecord    entry = CliDB.MapStorage.LookupByKey(pair.Key);
                if (entry == null || entry.IsRaid() != isRaid || !p.CanReset())
                {
                    continue;
                }

                if (method == InstanceResetMethod.All)
                {
                    // the "reset all instances" method can only reset normal maps
                    if (entry.InstanceType == MapTypes.Raid || diff == Difficulty.Heroic)
                    {
                        continue;
                    }
                }

                // if the map is loaded, reset it
                Map map = Global.MapMgr.FindMap(p.GetMapId(), p.GetInstanceId());
                if (map != null && map.IsDungeon())
                {
                    if (!map.ToInstanceMap().Reset(method))
                    {
                        continue;
                    }
                }

                // since this is a solo instance there should not be any players inside
                if (method == InstanceResetMethod.All || method == InstanceResetMethod.ChangeDifficulty)
                {
                    SendResetInstanceSuccess(p.GetMapId());
                }

                p.DeleteFromDB();
                m_boundInstances[(int)diff].Remove(pair.Key);

                // the following should remove the instance save from the manager and delete it as well
                p.RemovePlayer(this);
            }
        }
Пример #4
0
        public void SendCalendarRaidLockout(InstanceSave save, bool add)
        {
            long currTime = GameTime.GetGameTime();

            if (add)
            {
                CalendarRaidLockoutAdded calendarRaidLockoutAdded = new();
                calendarRaidLockoutAdded.InstanceID    = save.GetInstanceId();
                calendarRaidLockoutAdded.ServerTime    = (uint)currTime;
                calendarRaidLockoutAdded.MapID         = (int)save.GetMapId();
                calendarRaidLockoutAdded.DifficultyID  = save.GetDifficultyID();
                calendarRaidLockoutAdded.TimeRemaining = (int)(save.GetResetTime() - currTime);
                SendPacket(calendarRaidLockoutAdded);
            }
            else
            {
                CalendarRaidLockoutRemoved calendarRaidLockoutRemoved = new();
                calendarRaidLockoutRemoved.InstanceID   = save.GetInstanceId();
                calendarRaidLockoutRemoved.MapID        = (int)save.GetMapId();
                calendarRaidLockoutRemoved.DifficultyID = save.GetDifficultyID();
                SendPacket(calendarRaidLockoutRemoved);
            }
        }
Пример #5
0
        static bool HandleInstanceListBinds(StringArguments args, CommandHandler handler)
        {
            Player player = handler.GetSelectedPlayer();

            if (!player)
            {
                player = handler.GetSession().GetPlayer();
            }

            string format = "map: {0} inst: {1} perm: {2} diff: {3} canReset: {4} TTR: {5}";

            uint counter = 0;

            for (byte i = 0; i < (int)Difficulty.Max; ++i)
            {
                var binds = player.GetBoundInstances((Difficulty)i);
                foreach (var pair in binds)
                {
                    InstanceSave save     = pair.Value.save;
                    string       timeleft = Time.GetTimeString(save.GetResetTime() - Time.UnixTime);
                    handler.SendSysMessage(format, pair.Key, save.GetInstanceId(), pair.Value.perm ? "yes" : "no", save.GetDifficultyID(), save.CanReset() ? "yes" : "no", timeleft);
                    counter++;
                }
            }
            handler.SendSysMessage("player binds: {0}", counter);

            counter = 0;
            Group group = player.GetGroup();

            if (group)
            {
                for (byte i = 0; i < (int)Difficulty.Max; ++i)
                {
                    var binds = group.GetBoundInstances((Difficulty)i);
                    foreach (var pair in binds)
                    {
                        InstanceSave save     = pair.Value.save;
                        string       timeleft = Time.GetTimeString(save.GetResetTime() - Time.UnixTime);
                        handler.SendSysMessage(format, pair.Key, save.GetInstanceId(), pair.Value.perm ? "yes" : "no", save.GetDifficultyID(), save.CanReset() ? "yes" : "no", timeleft);
                        counter++;
                    }
                }
            }
            handler.SendSysMessage("group binds: {0}", counter);

            return(true);
        }
Пример #6
0
        void HandleCalendarGetCalendar(CalendarGetCalendar calendarGetCalendar)
        {
            ObjectGuid guid = GetPlayer().GetGUID();

            long currTime = GameTime.GetGameTime();

            CalendarSendCalendar packet = new();

            packet.ServerTime = currTime;

            var invites = Global.CalendarMgr.GetPlayerInvites(guid);

            foreach (var invite in invites)
            {
                CalendarSendCalendarInviteInfo inviteInfo = new();
                inviteInfo.EventID     = invite.EventId;
                inviteInfo.InviteID    = invite.InviteId;
                inviteInfo.InviterGuid = invite.SenderGuid;
                inviteInfo.Status      = invite.Status;
                inviteInfo.Moderator   = invite.Rank;
                CalendarEvent calendarEvent = Global.CalendarMgr.GetEvent(invite.EventId);
                if (calendarEvent != null)
                {
                    inviteInfo.InviteType = (byte)(calendarEvent.IsGuildEvent() && calendarEvent.GuildId == _player.GetGuildId() ? 1 : 0);
                }

                packet.Invites.Add(inviteInfo);
            }

            var playerEvents = Global.CalendarMgr.GetPlayerEvents(guid);

            foreach (var calendarEvent in playerEvents)
            {
                CalendarSendCalendarEventInfo eventInfo;
                eventInfo.EventID     = calendarEvent.EventId;
                eventInfo.Date        = calendarEvent.Date;
                eventInfo.EventClubID = calendarEvent.GuildId;
                eventInfo.EventName   = calendarEvent.Title;
                eventInfo.EventType   = calendarEvent.EventType;
                eventInfo.Flags       = calendarEvent.Flags;
                eventInfo.OwnerGuid   = calendarEvent.OwnerGuid;
                eventInfo.TextureID   = calendarEvent.TextureId;

                packet.Events.Add(eventInfo);
            }

            foreach (var difficulty in CliDB.DifficultyStorage.Values)
            {
                var boundInstances = _player.GetBoundInstances((Difficulty)difficulty.Id);
                if (boundInstances != null)
                {
                    foreach (var boundInstance in boundInstances.Values)
                    {
                        if (boundInstance.perm)
                        {
                            CalendarSendCalendarRaidLockoutInfo lockoutInfo;

                            InstanceSave save = boundInstance.save;
                            lockoutInfo.MapID        = (int)save.GetMapId();
                            lockoutInfo.DifficultyID = (uint)save.GetDifficultyID();
                            lockoutInfo.ExpireTime   = save.GetResetTime() - currTime;
                            lockoutInfo.InstanceID   = save.GetInstanceId(); // instance save id as unique instance copy id

                            packet.RaidLockouts.Add(lockoutInfo);
                        }
                    }
                }
            }

            SendPacket(packet);
        }
Пример #7
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);
            }
        }
Пример #8
0
        public InstanceBind BindToInstance(InstanceSave save, bool permanent, BindExtensionState extendState = BindExtensionState.Normal, bool load = false)
        {
            if (save != null)
            {
                InstanceBind bind = new InstanceBind();
                if (m_boundInstances[(int)save.GetDifficultyID()].ContainsKey(save.GetMapId()))
                {
                    bind = m_boundInstances[(int)save.GetDifficultyID()][save.GetMapId()];
                }

                if (extendState == BindExtensionState.Keep) // special flag, keep the player's current extend state when updating for new boss down
                {
                    if (save == bind.save)
                    {
                        extendState = bind.extendState;
                    }
                    else
                    {
                        extendState = BindExtensionState.Normal;
                    }
                }

                if (!load)
                {
                    PreparedStatement stmt;
                    if (bind.save != null)
                    {
                        // update the save when the group kills a boss
                        if (permanent != bind.perm || save != bind.save || extendState != bind.extendState)
                        {
                            stmt = DB.Characters.GetPreparedStatement(CharStatements.UPD_CHAR_INSTANCE);

                            stmt.AddValue(0, save.GetInstanceId());
                            stmt.AddValue(1, permanent);
                            stmt.AddValue(2, extendState);
                            stmt.AddValue(3, GetGUID().GetCounter());
                            stmt.AddValue(4, bind.save.GetInstanceId());

                            DB.Characters.Execute(stmt);
                        }
                    }
                    else
                    {
                        stmt = DB.Characters.GetPreparedStatement(CharStatements.INS_CHAR_INSTANCE);
                        stmt.AddValue(0, GetGUID().GetCounter());
                        stmt.AddValue(1, save.GetInstanceId());
                        stmt.AddValue(2, permanent);
                        stmt.AddValue(3, extendState);
                        DB.Characters.Execute(stmt);
                    }
                }

                if (bind.save != save)
                {
                    if (bind.save != null)
                    {
                        bind.save.RemovePlayer(this);
                    }
                    save.AddPlayer(this);
                }

                if (permanent)
                {
                    save.SetCanReset(false);
                }

                bind.save        = save;
                bind.perm        = permanent;
                bind.extendState = extendState;
                if (!load)
                {
                    Log.outDebug(LogFilter.Maps, "Player.BindToInstance: Player '{0}' ({1}) is now bound to map (ID: {2}, Instance {3}, Difficulty {4})", GetName(), GetGUID().ToString(), save.GetMapId(), save.GetInstanceId(), save.GetDifficultyID());
                }

                Global.ScriptMgr.OnPlayerBindToInstance(this, save.GetDifficultyID(), save.GetMapId(), permanent, extendState);

                m_boundInstances[(int)save.GetDifficultyID()][save.GetMapId()] = bind;
                return(bind);
            }

            return(null);
        }
Пример #9
0
        static bool HandleInstanceUnbind(StringArguments args, CommandHandler handler)
        {
            if (args.Empty())
            {
                return(false);
            }

            Player player = handler.GetSelectedPlayer();

            if (!player)
            {
                player = handler.GetSession().GetPlayer();
            }

            string map = args.NextString();

            if (!sbyte.TryParse(args.NextString(), out sbyte diff))
            {
                diff = -1;
            }

            ushort counter = 0;
            ushort MapId   = 0;

            if (map != "all")
            {
                if (!ushort.TryParse(map, out MapId) || MapId == 0)
                {
                    return(false);
                }
            }

            for (byte i = 0; i < (int)Difficulty.Max; ++i)
            {
                var binds = player.GetBoundInstances((Difficulty)i);
                foreach (var pair in binds)
                {
                    InstanceSave save = pair.Value.save;
                    if (pair.Key != player.GetMapId() && (MapId == 0 || MapId == pair.Key) && (diff == -1 || diff == (sbyte)save.GetDifficultyID()))
                    {
                        string timeleft = Time.GetTimeString(save.GetResetTime() - Time.UnixTime);
                        handler.SendSysMessage("unbinding map: {0} inst: {1} perm: {2} diff: {3} canReset: {4} TTR: {5}", pair.Key, save.GetInstanceId(),
                                               pair.Value.perm ? "yes" : "no", save.GetDifficultyID(), save.CanReset() ? "yes" : "no", timeleft);
                        player.UnbindInstance(pair.Key, (Difficulty)i);
                        counter++;
                    }
                }
            }
            handler.SendSysMessage("instances unbound: {0}", counter);

            return(true);
        }