Esempio n. 1
0
void Group::ResetInstances(InstanceResetMethod method, Player* SendMsgTo)
{
    if (isBGGroup())
        return;

    // method can be INSTANCE_RESET_ALL, INSTANCE_RESET_GROUP_DISBAND

    for (BoundInstancesMap::iterator itr = m_boundInstances.begin(); itr != m_boundInstances.end();)
    {
        DungeonPersistentState* state = itr->second.state;
        const MapEntry* entry = sMapStore.LookupEntry(itr->first);
        if (!entry || (!state->CanReset() && method != INSTANCE_RESET_GROUP_DISBAND))
        {
            ++itr;
            continue;
        }

        if (method == INSTANCE_RESET_ALL)
        {
            // the "reset all instances" method can only reset normal maps
            if (entry->map_type == MAP_RAID)
            {
                ++itr;
                continue;
            }
        }

        bool isEmpty = true;
        // if the map is loaded, reset it
        if (Map* map = sMapMgr.FindMap(state->GetMapId(), state->GetInstanceId()))
            if (map->IsDungeon() && !(method == INSTANCE_RESET_GROUP_DISBAND && !state->CanReset()))
                isEmpty = ((DungeonMap*)map)->Reset(method);

        if (SendMsgTo)
        {
            if (isEmpty)
                SendMsgTo->SendResetInstanceSuccess(state->GetMapId());
            else
                SendMsgTo->SendResetInstanceFailed(0, state->GetMapId());
        }

        if (isEmpty || method == INSTANCE_RESET_GROUP_DISBAND)
        {
            // do not reset the instance, just unbind if others are permanently bound to it
            if (state->CanReset())
                state->DeleteFromDB();
            else
                CharacterDatabase.PExecute("DELETE FROM group_instance WHERE instance = '%u'", state->GetInstanceId());
            // i don't know for sure if hash_map iterators
            m_boundInstances.erase(itr);
            itr = m_boundInstances.begin();
            // this unloads the instance save unless online players are bound to it
            // (eg. permanent binds or GM solo binds)
            state->RemoveGroup(this);
        }
        else
            ++itr;
    }
}
Esempio n. 2
0
void InstanceData::SendSpecialEncounterState(ObjectGuid linkedGuid)
{
    DungeonPersistentState* state = ((DungeonMap*)instance)->GetPersistanceState();
    if (!state)
        return;

    state->SendSpecialEncounterState(linkedGuid);
}
Esempio n. 3
0
void InstanceData::UpdateSpecialEncounterState(EncounterFrameCommand command, ObjectGuid linkedGuid, uint8 data1, uint8 data2)
{
    DungeonPersistentState* state = ((DungeonMap*)instance)->GetPersistanceState();
    if (!state)
        return;

    state->UpdateSpecialEncounterState(command, linkedGuid, data1, data2);
}
/*
- adding instance into manager
- called from DungeonMap::Add, _LoadBoundInstances, LoadGroups
*/
MapPersistentState* MapPersistentStateManager::AddPersistentState(MapEntry const* mapEntry, uint32 instanceId, Difficulty difficulty, time_t resetTime, bool canReset, bool load /*=false*/, bool initPools /*= true*/, uint32 completedEncountersMask /*= 0*/)
{
    if (MapPersistentState *old_save = GetPersistentState(mapEntry->MapID, instanceId))
        return old_save;

    if (mapEntry->IsDungeon())
    {
        if (!resetTime || resetTime < time(NULL))
        {
            // initialize reset time
            // for normal instances if no creatures are killed the instance will reset in two hours
            if (mapEntry->map_type == MAP_RAID || difficulty > DUNGEON_DIFFICULTY_NORMAL)
                resetTime = m_Scheduler.GetResetTimeFor(mapEntry->MapID, difficulty);
            else
            {
                resetTime = time(NULL) + 2 * HOUR;
                // normally this will be removed soon after in DungeonMap::Add, prevent error
                m_Scheduler.ScheduleReset(true, resetTime, DungeonResetEvent(RESET_EVENT_NORMAL_DUNGEON, mapEntry->MapID, difficulty, instanceId));
            }
        }
    }

    DEBUG_LOG("MapPersistentStateManager::AddPersistentState: mapid = %d, instanceid = %d, reset time = '" UI64FMTD "', canRset = %u", mapEntry->MapID, instanceId, uint64(resetTime), canReset ? 1 : 0);

    MapPersistentState* state = NULL;
    if (mapEntry->IsDungeon() && instanceId)
    {
        DungeonPersistentState* dungeonState = new DungeonPersistentState(mapEntry->MapID, instanceId, difficulty, resetTime, canReset, completedEncountersMask);
        if (!load)
            dungeonState->SaveToDB();
        state = dungeonState;
    }
    else if (mapEntry->IsBattleGroundOrArena())
        state = new BattleGroundPersistentState(mapEntry->MapID, instanceId, difficulty);
    else if (!instanceId)
        state = new WorldPersistentState(mapEntry->MapID);
    else
    {
        sLog.outError("MapPersistentStateManager::AddPersistentState cannot create persistent state for mapid = %d, instanceid = %d, reset time = %ld, canReset = %u", mapEntry->MapID, instanceId, resetTime, canReset ? 1 : 0);
        return state;
    }


    if (state && instanceId)
        m_instanceSaveByInstanceId[instanceId] = state;
    else if (state && !instanceId)
        m_instanceSaveByMapId[mapEntry->MapID] = state;

    if (state && initPools)
        state->InitPools();

    if (state)
        sWorldStateMgr.CreateInstanceState(mapEntry->MapID, instanceId);

    return state;
}
Esempio n. 5
0
/*
- adding instance into manager
- called from DungeonMap::Add, _LoadBoundInstances, LoadGroups
*/
MapPersistentState* MapPersistentStateManager::AddPersistentState(MapEntry const* mapEntry, uint32 instanceId, time_t resetTime, bool canReset, bool load /*=false*/, bool initPools /*= true*/)
{
    if (MapPersistentState *old_save = GetPersistentState(mapEntry->MapID, instanceId))
        return old_save;

    if (mapEntry->IsDungeon())
    {
        if (!resetTime)
        {
            // initialize reset time
            // for normal instances if no creatures are killed the instance will reset in two hours
            if(mapEntry->map_type == MAP_RAID)
                resetTime = m_Scheduler.GetResetTimeFor(mapEntry->MapID);
            else
            {
                resetTime = time(NULL) + 2 * HOUR;
                // normally this will be removed soon after in DungeonMap::Add, prevent error
                m_Scheduler.ScheduleReset(true, resetTime, DungeonResetEvent(RESET_EVENT_NORMAL_DUNGEON, mapEntry->MapID, instanceId));
            }
        }
    }

    DEBUG_LOG("MapPersistentStateManager::AddPersistentState: mapid = %d, instanceid = %d, reset time = %u, canRset = %u", mapEntry->MapID, instanceId, resetTime, canReset ? 1 : 0);

    MapPersistentState *state;
    if (mapEntry->IsDungeon())
    {
        DungeonPersistentState* dungeonState = new DungeonPersistentState(mapEntry->MapID, instanceId, resetTime, canReset);
        if (!load)
            dungeonState->SaveToDB();
        state = dungeonState;
    }
    else if (mapEntry->IsBattleGround())
        state = new BattleGroundPersistentState(mapEntry->MapID, instanceId);
    else
        state = new WorldPersistentState(mapEntry->MapID);

    if (instanceId)
        m_instanceSaveByInstanceId[instanceId] = state;
    else
        m_instanceSaveByMapId[mapEntry->MapID] = state;

    if (initPools)
        state->InitPools();

    return state;
}
Esempio n. 6
0
void Group::ResetInstances(InstanceResetMethod method, bool isRaid, Player* SendMsgTo)
{
    if (isBGGroup())
        return;

    // method can be INSTANCE_RESET_ALL, INSTANCE_RESET_CHANGE_DIFFICULTY, INSTANCE_RESET_GROUP_DISBAND

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

    typedef std::set<uint32> OfflineMapSet;
    OfflineMapSet mapsWithOfflinePlayer;                    // to store map of offline players

    if (method != INSTANCE_RESET_GROUP_DISBAND)
    {
        // Store maps in which are offline members for instance reset check.
        for (member_citerator itr = m_memberSlots.begin(); itr != m_memberSlots.end(); ++itr)
        {
            if (!ObjectAccessor::FindPlayer(itr->guid))
                mapsWithOfflinePlayer.insert(itr->lastMap); // add last map from offline player
        }
    }

    for (BoundInstancesMap::iterator itr = m_boundInstances[diff].begin(); itr != m_boundInstances[diff].end();)
    {
        DungeonPersistentState* state = itr->second.state;
        const MapEntry* entry = sMapStore.LookupEntry(itr->first);
        if (!entry || entry->IsRaid() != isRaid || (!state->CanReset() && method != INSTANCE_RESET_GROUP_DISBAND))
        {
            ++itr;
            continue;
        }

        if (method == INSTANCE_RESET_ALL)
        {
            // the "reset all instances" method can only reset normal maps
            if (entry->map_type == MAP_RAID || diff == DUNGEON_DIFFICULTY_HEROIC)
            {
                ++itr;
                continue;
            }
        }

        bool isEmpty = true;
        // check if there are offline members on the map
        if (method != INSTANCE_RESET_GROUP_DISBAND && mapsWithOfflinePlayer.find(state->GetMapId()) != mapsWithOfflinePlayer.end())
            isEmpty = false;

        // if the map is loaded, reset it if can
        if (isEmpty && entry->IsDungeon() && !(method == INSTANCE_RESET_GROUP_DISBAND && !state->CanReset()))
            if (Map* map = sMapMgr.FindMap(state->GetMapId(), state->GetInstanceId()))
                isEmpty = ((DungeonMap*)map)->Reset(method);

        if (SendMsgTo)
        {
            if (isEmpty)
                SendMsgTo->SendResetInstanceSuccess(state->GetMapId());
            else
                SendMsgTo->SendResetInstanceFailed(0, state->GetMapId());
        }

        // TODO - Adapt here when clear how difficulty changes must be handled
        if (isEmpty || method == INSTANCE_RESET_GROUP_DISBAND || method == INSTANCE_RESET_CHANGE_DIFFICULTY)
        {
            // do not reset the instance, just unbind if others are permanently bound to it
            if (state->CanReset())
                state->DeleteFromDB();
            else
                CharacterDatabase.PExecute("DELETE FROM group_instance WHERE instance = '%u'", state->GetInstanceId());
            // i don't know for sure if hash_map iterators
            m_boundInstances[diff].erase(itr);
            itr = m_boundInstances[diff].begin();
            // this unloads the instance save unless online players are bound to it
            // (eg. permanent binds or GM solo binds)
            state->RemoveGroup(this);
        }
        else
            ++itr;
    }
}
Esempio n. 7
0
void WorldSession::HandleCalendarGetCalendar(WorldPacket &/*recv_data*/)
{
    DEBUG_LOG("WORLD: CMSG_CALENDAR_GET_CALENDAR");     // empty

    time_t cur_time = time(NULL);

    WorldPacket data(SMSG_CALENDAR_SEND_CALENDAR,4+4*0+4+4*0+4+4);

    // TODO: calendar invite event output
    data << (uint32) 0;                                     //invite node count
    // TODO: calendar event output
    data << (uint32) 0;                                     //event count

    data << uint32(cur_time);                               // current time, unix timestamp
    data << uint32(secsToTimeBitFields(cur_time));          // current time, time bit fields

    uint32 counter = 0;
    size_t p_counter = data.wpos();
    data << uint32(counter);                                // instance state count

    for(int i = 0; i < MAX_DIFFICULTY; ++i)
    {
        for (Player::BoundInstancesMap::const_iterator itr = _player->m_boundInstances[i].begin(); itr != _player->m_boundInstances[i].end(); ++itr)
        {
            if(itr->second.perm)
            {
                DungeonPersistentState *state = itr->second.state;
                data << uint32(state->GetMapId());
                data << uint32(state->GetDifficulty());
                data << uint32(state->GetResetTime() - cur_time);
                data << ObjectGuid(state->GetInstanceGuid());
                ++counter;
            }
        }
    }
    data.put<uint32>(p_counter,counter);

    data << uint32(INSTANCE_RESET_SCHEDULE_START_TIME + sWorld.getConfig(CONFIG_UINT32_INSTANCE_RESET_TIME_HOUR) * HOUR);
    counter = 0;
    p_counter = data.wpos();
    data << uint32(counter);                                // Instance reset intervals
    for(MapDifficultyMap::const_iterator itr = sMapDifficultyMap.begin(); itr != sMapDifficultyMap.end(); ++itr)
    {
        MapDifficultyEntry const* mapDiff = itr->second;

        if(!mapDiff || mapDiff->resetTime == 0)
            continue;

        const MapEntry* map = sMapStore.LookupEntry(mapDiff->MapId);
        if(!map || !map->IsRaid())
            continue;

        uint32 period =  uint32(mapDiff->resetTime / DAY * sWorld.getConfig(CONFIG_FLOAT_RATE_INSTANCE_RESET_TIME)) * DAY;
        if (period < DAY)
            period = DAY;

        data << uint32(mapDiff->MapId);
        data << uint32(period);
        data << uint32(mapDiff->resetTime);
        ++counter;
    }
    data.put<uint32>(p_counter,counter);

    data << (uint32) 0;                                     // unk counter 5
    //DEBUG_LOG("Sending calendar");
    //data.hexlike();
    SendPacket(&data);
}
Esempio n. 8
0
void Group::ResetInstances(InstanceResetMethod method, Player* SendMsgTo)
{
    if (isBattleGroup())
        return;

    // method can be INSTANCE_RESET_ALL, INSTANCE_RESET_GROUP_DISBAND

    typedef std::set<uint32> Uint32Set;
    Uint32Set mapsWithOfflinePlayer;                        // to store map of offline players
    Uint32Set mapsWithBeingTeleportedPlayer;                // to store map of offline players

    if (method != INSTANCE_RESET_GROUP_DISBAND)
    {
        // Store maps in which are offline members for instance reset check.
        for (member_citerator itr = m_memberSlots.begin(); itr != m_memberSlots.end(); ++itr)
        {
            Player* plr = ObjectAccessor::FindPlayer(itr->guid);
            if (!plr)
            {
                // add last map from offline player
                mapsWithOfflinePlayer.insert(itr->lastMap);
            }
            else
            {
                // add teleport destination map
                if (plr->IsBeingTeleported())
                    mapsWithBeingTeleportedPlayer.insert(plr->GetTeleportDest().mapid);
            }
        }
    }

    for (BoundInstancesMap::iterator itr = m_boundInstances.begin(); itr != m_boundInstances.end();)
    {
        DungeonPersistentState* state = itr->second.state;
        const MapEntry* entry = sMapStore.LookupEntry(itr->first);
        if (!entry || (!state->CanReset() && method != INSTANCE_RESET_GROUP_DISBAND))
        {
            ++itr;
            continue;
        }

        if (method == INSTANCE_RESET_ALL)
        {
            // the "reset all instances" method can only reset normal maps
            if (entry->map_type == MAP_RAID)
            {
                ++itr;
                continue;
            }
        }

        // check if there are offline members on the map
        if (method != INSTANCE_RESET_GROUP_DISBAND && mapsWithOfflinePlayer.find(state->GetMapId()) != mapsWithOfflinePlayer.end())
        {
            if (SendMsgTo)
                SendMsgTo->SendResetInstanceFailed(1, state->GetMapId());
            ++itr;
            continue;
        }

        // check if there are teleporting members to the map
        if (method != INSTANCE_RESET_GROUP_DISBAND && mapsWithBeingTeleportedPlayer.find(state->GetMapId()) != mapsWithBeingTeleportedPlayer.end())
        {
            if (SendMsgTo)
                SendMsgTo->SendResetInstanceFailed(2, state->GetMapId());
            ++itr;
            continue;
        }

        bool isEmpty = true;
        // if the map is loaded, reset it if can
        if (entry->IsDungeon() && !(method == INSTANCE_RESET_GROUP_DISBAND && !state->CanReset()))
            if (Map* map = sMapMgr.FindMap(state->GetMapId(), state->GetInstanceId()))
                isEmpty = ((DungeonMap*)map)->Reset(method);

        if (SendMsgTo)
        {
            if (isEmpty)
                SendMsgTo->SendResetInstanceSuccess(state->GetMapId());
            else
                SendMsgTo->SendResetInstanceFailed(0, state->GetMapId());
        }

        if (isEmpty || method == INSTANCE_RESET_GROUP_DISBAND)
        {
            // do not reset the instance, just unbind if others are permanently bound to it
            if (state->CanReset())
                state->DeleteFromDB();
            else
                CharacterDatabase.PExecute("DELETE FROM group_instance WHERE instance = '%u'", state->GetInstanceId());
            // i don't know for sure if hash_map iterators
            m_boundInstances.erase(itr);
            itr = m_boundInstances.begin();
            // this unloads the instance save unless online players are bound to it
            // (eg. permanent binds or GM solo binds)
            state->RemoveGroup(this);
        }
        else
            ++itr;
    }
}
Esempio n. 9
0
void WorldSession::HandleCalendarGetCalendar(WorldPacket &/*recv_data*/)
{
    DEBUG_LOG("WORLD: CMSG_CALENDAR_GET_CALENDAR");         // empty

    time_t cur_time = time(NULL);

    WorldPacket data(SMSG_CALENDAR_SEND_CALENDAR, 4+4*0+4+4*0+4+4);

    // TODO: calendar invite event output
    data << (uint32) 0;                                     // invite node count
    // TODO: calendar event output
    data << (uint32) 0;                                     // event count

    data << (uint32) 0;                                     // Current Unix Time?
    data << (uint32) secsToTimeBitFields(cur_time);         // current packed time

    uint32 counter = 0;
    size_t p_counter = data.wpos();
    data << uint32(counter);                                // instance state count

    for(int i = 0; i < MAX_DIFFICULTY; ++i)
    {
        for (Player::BoundInstancesMap::const_iterator itr = _player->m_boundInstances[i].begin(); itr != _player->m_boundInstances[i].end(); ++itr)
        {
            if(itr->second.perm)
            {
                DungeonPersistentState *state = itr->second.state;
                data << uint32(state->GetMapId());
                data << uint32(state->GetDifficulty());
                data << uint32(state->GetResetTime() - cur_time);
                data << ObjectGuid(state->GetInstanceGuid());
                ++counter;
            }
        }
    }
    data.put<uint32>(p_counter,counter);

    data << (uint32) 1135753200;                            // base date (28.12.2005 12:00)
    data << (uint32) 0;                                     // raid reset count
    data << (uint32) 0;                                     // holidays count
    /*
        for(uint32 i = 0; i < holidays_count; ++i)
        {
            data << uint32(0);                                  // Holidays.dbc ID
            data << uint32(0);                                  // Holidays.dbc region
            data << uint32(0);                                  // Holidays.dbc looping
            data << uint32(0);                                  // Holidays.dbc priority
            data << uint32(0);                                  // Holidays.dbc calendarFilterType

            for(uint32 j = 0; j < 26; j++)
                data << uint32(0);                              // Holidays.dbc date

            for(uint32 j = 0; j < 10; j++)
                data << uint32(0);                              // Holidays.dbc duration

            for(uint32 j = 0; j < 10; j++)
                data << uint32(0);                              // Holidays.dbc calendarFlags

            data << "";                                         // Holidays.dbc textureFilename
        }
    */
    //DEBUG_LOG("Sending calendar");
    //data.hexlike();
    SendPacket(&data);
}