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; } }
void InstanceData::SendSpecialEncounterState(ObjectGuid linkedGuid) { DungeonPersistentState* state = ((DungeonMap*)instance)->GetPersistanceState(); if (!state) return; state->SendSpecialEncounterState(linkedGuid); }
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; }
/* - 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; }
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; } }
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); }
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; } }
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); }