void MapPersistentStateManager::LoadGameobjectRespawnTimes()
{
    // remove outdated data
    CharacterDatabase.DirectExecute("DELETE FROM gameobject_respawn WHERE respawntime <= UNIX_TIMESTAMP(NOW())");

    uint32 count = 0;

    QueryResult *result = CharacterDatabase.Query("SELECT guid, respawntime, map, instance, resettime FROM gameobject_respawn LEFT JOIN instance ON instance = id");

    if(!result)
    {
        barGoLink bar(1);

        bar.step();

        sLog.outString();
        sLog.outString(">> Loaded 0 gameobject respawn time.");
        return;
    }

    barGoLink bar((int)result->GetRowCount());

    do
    {
        Field *fields = result->Fetch();
        bar.step();

        uint32 loguid       = fields[0].GetUInt32();
        uint64 respawn_time = fields[1].GetUInt64();
        uint32 mapId        = fields[2].GetUInt32();
        uint32 instanceId   = fields[3].GetUInt32();

        time_t resetTime = (time_t)fields[4].GetUInt64();

        GameObjectData const* data = sObjectMgr.GetGOData(loguid);
        if (!data)
            continue;

        if (mapId != data->mapid)
            continue;

        MapEntry const* mapEntry = sMapStore.LookupEntry(mapId);
        if (!mapEntry || (mapEntry->Instanceable() != (instanceId != 0)))
            continue;

        MapPersistentState* state = AddPersistentState(mapEntry, instanceId, resetTime, mapEntry->IsDungeon(), true);
        if (!state)
            continue;

        state->SetGORespawnTime(loguid, time_t(respawn_time));

        ++count;

    } while (result->NextRow());

    delete result;

    sLog.outString(">> Loaded %u gameobject respawn times", count);
    sLog.outString();
}
void MapPersistentStateManager::InitWorldMaps()
{
    MapPersistentState* state = nullptr;                       // need any from created for shared pool state
    for (uint32 mapid = 0; mapid < sMapStore.GetNumRows(); ++mapid)
        if (MapEntry const* entry = sMapStore.LookupEntry(mapid))
            if (!entry->Instanceable())
                state = AddPersistentState(entry, 0, REGULAR_DIFFICULTY, 0, false, true, false);

    if (state)
        state->InitPools();
}
void MapPersistentStateManager::LoadCreatureRespawnTimes()
{
    // remove outdated data
    CharacterDatabase.DirectExecute("DELETE FROM creature_respawn WHERE respawntime <= UNIX_TIMESTAMP(NOW())");

    uint32 count = 0;

    //                                                    0     1            2    3         4           5          6
    QueryResult* result = CharacterDatabase.Query("SELECT guid, respawntime, map, instance, difficulty, resettime, encountersMask FROM creature_respawn LEFT JOIN instance ON instance = id");
    if (!result)
    {
        BarGoLink bar(1);
        bar.step();
        sLog.outString(">> Loaded 0 creature respawn time.");
        sLog.outString();
        return;
    }

    BarGoLink bar(result->GetRowCount());

    do
    {
        Field* fields = result->Fetch();
        bar.step();

        uint32 loguid               = fields[0].GetUInt32();
        uint64 respawn_time         = fields[1].GetUInt64();
        uint32 mapId                = fields[2].GetUInt32();
        uint32 instanceId           = fields[3].GetUInt32();
        uint8 difficulty            = fields[4].GetUInt8();
        time_t resetTime            = (time_t)fields[5].GetUInt64();
        uint32 completedEncounters = fields[6].GetUInt32();

        CreatureData const* data = sObjectMgr.GetCreatureData(loguid);
        if (!data)
            continue;

        MapEntry const* mapEntry = sMapStore.LookupEntry(data->mapid);
        if (!mapEntry)
            continue;

        if (instanceId)                                     // In instance - mapId must be data->mapid and mapEntry must be Instanceable
        {
            if (mapId != data->mapid || !mapEntry->Instanceable())
                continue;
        }
        else                                                // Not in instance, mapEntry must not be Instanceable
        {
            if (mapEntry->Instanceable())
                continue;
        }

        if (difficulty >= (!mapEntry->Instanceable() ? REGULAR_DIFFICULTY + 1 : MAX_DIFFICULTY))
            continue;

        MapPersistentState* state = AddPersistentState(mapEntry, instanceId, Difficulty(difficulty), resetTime, mapEntry->IsDungeon(), true, true, completedEncounters);
        if (!state)
            continue;

        state->SetCreatureRespawnTime(loguid, time_t(respawn_time));

        ++count;
    }
    while (result->NextRow());

    delete result;

    sLog.outString(">> Loaded %u creature respawn times", count);
    sLog.outString();
}