Jump to content

[10534][FIX] InstanceResetScheduler in case Server running longer than 2 days


Auntie Mangos

Recommended Posts

  • 40 years later...

What Bug is this about?

When a server is up longer than 2 days the heroic instances don't get resetted anymore.

What version was this Bug written for?

MaNGOS-0.12 up2date; as far as I read the code this could be a problem in Master too.

Who tracked the error down and wrote the change?

Funkybit and Baileys

Description of Bug in Detail:

I have to restart my server at least every 2 days otherwise the daily or raid instances don't get their ID killed in the morning.

So I noticed that 'm_resetTimeQueue' was about 32 entries right after server start but after a daily reset of heroic instances it only contains 17 entries.

This concludes for me to:

After you start your server, the heroic instances get resetted once normaly when the schedule event expires. Than after an other day there is no event to expire again because when the last one for that map was executed it gets deleted but not readded to the queue.

So we need to re-add it as it already happens in the 'event.type != RESET_EVENT_INFORM_LAST' case of the 'ScheduleReset(..)' method. This way we can ensure that there is always an event for each map that can expire and delete all the instance id's in the database.

diff --git a/src/game/InstanceSaveMgr.cpp b/src/game/InstanceSaveMgr.cpp
index bc8d89d..267a751 100644
--- a/src/game/InstanceSaveMgr.cpp
+++ b/src/game/InstanceSaveMgr.cpp
@@ -287,28 +287,45 @@ void InstanceResetScheduler::ScheduleReset(bool add, time_t time, InstanceResetE
void InstanceResetScheduler::Update()
{
    time_t now = time(NULL), t;
-    while(!m_resetTimeQueue.empty() && (t = m_resetTimeQueue.begin()->first) < now)
+    while (!m_resetTimeQueue.empty() && (t = m_resetTimeQueue.begin()->first) < now)
    {
        InstanceResetEvent &event = m_resetTimeQueue.begin()->second;
-        if(event.type == RESET_EVENT_DUNGEON)
+        if (event.type == RESET_EVENT_DUNGEON)
        {
            // for individual normal instances, max creature respawn + X hours
            m_InstanceSaves._ResetInstance(event.mapid, event.instanceId);
-            m_resetTimeQueue.erase(m_resetTimeQueue.begin());
        }
        else
        {
-            // global reset/warning for a certain map
+            // global reset/warning for a certain map (heroic/raid)
            time_t resetTime = GetResetTimeFor(event.mapid);
            m_InstanceSaves._ResetOrWarnAll(event.mapid, event.type != RESET_EVENT_INFORM_LAST, uint32(resetTime - now));
-            if(event.type != RESET_EVENT_INFORM_LAST)
+            if (event.type != RESET_EVENT_INFORM_LAST)
            {
                // schedule the next warning/reset
                event.type = ResetEventType(event.type+1);
                ScheduleReset(true, resetTime - resetEventTypeDelay[event.type], event);
            }
-            m_resetTimeQueue.erase(m_resetTimeQueue.begin());
+            else
+            {
+                // re-schedule the next/new global reset/warning
+                // calculate the next reset time
+                InstanceTemplate const* temp = ObjectMgr::GetInstanceTemplate(event.mapid);
+                uint32 diff = sWorld.getConfig(CONFIG_UINT32_INSTANCE_RESET_TIME_HOUR) * HOUR;
+                uint32 period = InstanceResetScheduler::GetMaxResetTimeFor(temp);
+                time_t next_reset = ((resetTime + MINUTE) / DAY * DAY) + period + diff;
+
+                ResetEventType type = RESET_EVENT_INFORM_1;
+                for (; type < RESET_EVENT_INFORM_LAST; type = ResetEventType(type+1))
+                    if (next_reset - resetEventTypeDelay[type] > now)
+                        break;
+
+                // add new scheduler event to the queue
+                event.type = type;
+                ScheduleReset(true, next_reset - resetEventTypeDelay[event.type], event);
+            }
        }
+        m_resetTimeQueue.erase(m_resetTimeQueue.begin());
    }
}

http://gist.github.com/593766

http://pastebin.com/mT6fHn0y

So, I'm not really shure if this is the right way to do and would be happy to discuss this if any of you thinks it's wrong.

Greets!

Funkybit

Link to comment
Share on other sites

4>..\\..\\src\\game\\InstanceSaveMgr.cpp(338) : error C2664: 'InstanceResetScheduler::GetMaxResetTimeFor' : cannot convert parameter 1 from 'const InstanceTemplate *' to 'const MapDifficulty *'

Maybe this can correct it?

-                InstanceTemplate const* temp = ObjectMgr::GetInstanceTemplate(event.mapid);
+                MapDifficulty const* temp = GetMapDifficultyData(event.mapid,event.difficulty);
               uint32 diff = sWorld.getConfig(CONFIG_UINT32_INSTANCE_RESET_TIME_HOUR) * HOUR;
               uint32 period = InstanceResetScheduler::GetMaxResetTimeFor(temp);

Link to comment
Share on other sites

Guest
This topic is now closed to further replies.
×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue. Privacy Policy Terms of Use