void InstanceSaveManager::Unload() { lock_instLists = true; for (InstanceSaveHashMap::iterator itr = m_instanceSaveById.begin(); itr != m_instanceSaveById.end(); ++itr) { InstanceSave* save = itr->second; for (InstanceSave::PlayerListType::iterator itr2 = save->m_playerList.begin(), next = itr2; itr2 != save->m_playerList.end(); itr2 = next) { ++next; (*itr2)->UnbindInstance(save->GetMapId(), save->GetDifficultyID(), true); } for (InstanceSave::GroupListType::iterator itr2 = save->m_groupList.begin(), next = itr2; itr2 != save->m_groupList.end(); itr2 = next) { ++next; (*itr2)->UnbindInstance(save->GetMapId(), save->GetDifficultyID(), true); } delete save; } }
static bool HandleInstanceListBindsCommand(ChatHandler* handler, char const* /*args*/) { Player* player = handler->getSelectedPlayer(); if (!player) player = handler->GetSession()->GetPlayer(); uint32 counter = 0; for (uint8 i = 0; i < MAX_DIFFICULTY; ++i) { Player::BoundInstancesMap &binds = player->GetBoundInstances(Difficulty(i)); for (Player::BoundInstancesMap::const_iterator itr = binds.begin(); itr != binds.end(); ++itr) { InstanceSave* save = itr->second.save; std::string timeleft = GetTimeString(save->GetResetTime() - time(NULL)); handler->PSendSysMessage(LANG_COMMAND_LIST_BIND_INFO, itr->first, save->GetInstanceId(), itr->second.perm ? "yes" : "no", save->GetDifficultyID(), save->CanReset() ? "yes" : "no", timeleft.c_str()); counter++; } } handler->PSendSysMessage(LANG_COMMAND_LIST_BIND_PLAYER_BINDS, counter); counter = 0; if (Group* group = player->GetGroup()) { for (uint8 i = 0; i < MAX_DIFFICULTY; ++i) { Group::BoundInstancesMap &binds = group->GetBoundInstances(Difficulty(i)); for (Group::BoundInstancesMap::const_iterator itr = binds.begin(); itr != binds.end(); ++itr) { InstanceSave* save = itr->second.save; std::string timeleft = GetTimeString(save->GetResetTime() - time(NULL)); handler->PSendSysMessage(LANG_COMMAND_LIST_BIND_INFO, itr->first, save->GetInstanceId(), itr->second.perm ? "yes" : "no", save->GetDifficultyID(), save->CanReset() ? "yes" : "no", timeleft.c_str()); counter++; } } } handler->PSendSysMessage(LANG_COMMAND_LIST_BIND_GROUP_BINDS, counter); return true; }
static bool HandleInstanceUnbindCommand(ChatHandler* handler, char const* args) { if (!*args) return false; Player* player = handler->getSelectedPlayer(); if (!player) player = handler->GetSession()->GetPlayer(); char* map = strtok((char*)args, " "); char* pDiff = strtok(NULL, " "); int8 diff = -1; if (pDiff) diff = atoi(pDiff); uint16 counter = 0; uint16 MapId = 0; if (strcmp(map, "all") != 0) { MapId = uint16(atoi(map)); if (!MapId) return false; } for (uint8 i = 0; i < MAX_DIFFICULTY; ++i) { Player::BoundInstancesMap &binds = player->GetBoundInstances(Difficulty(i)); for (Player::BoundInstancesMap::iterator itr = binds.begin(); itr != binds.end();) { InstanceSave* save = itr->second.save; if (itr->first != player->GetMapId() && (!MapId || MapId == itr->first) && (diff == -1 || diff == save->GetDifficultyID())) { std::string timeleft = GetTimeString(save->GetResetTime() - time(NULL)); handler->PSendSysMessage(LANG_COMMAND_INST_UNBIND_UNBINDING, itr->first, save->GetInstanceId(), itr->second.perm ? "yes" : "no", save->GetDifficultyID(), save->CanReset() ? "yes" : "no", timeleft.c_str()); player->UnbindInstance(itr, Difficulty(i)); counter++; } else ++itr; } } handler->PSendSysMessage(LANG_COMMAND_INST_UNBIND_UNBOUND, counter); return true; }
/* - return the right instance for the object, based on its InstanceId - create the instance if it's not created already - the player is not actually added to the instance (only in InstanceMap::Add) */ Map* MapInstanced::CreateInstanceForPlayer(const uint32 mapId, Player* player) { if (GetId() != mapId || !player) return NULL; Map* map = NULL; uint32 newInstanceId = 0; // instanceId of the resulting map if (IsBattlegroundOrArena()) { // instantiate or find existing bg map for player // the instance id is set in battlegroundid newInstanceId = player->GetBattlegroundId(); if (!newInstanceId) return NULL; map = sMapMgr->FindMap(mapId, newInstanceId); if (!map) { if (Battleground* bg = player->GetBattleground()) map = CreateBattleground(newInstanceId, bg); else { player->TeleportToBGEntryPoint(); return NULL; } } } else if (!IsGarrison()) { InstancePlayerBind* pBind = player->GetBoundInstance(GetId(), player->GetDifficultyID(GetEntry())); InstanceSave* pSave = pBind ? pBind->save : NULL; // the player's permanent player bind is taken into consideration first // then the player's group bind and finally the solo bind. if (!pBind || !pBind->perm) { InstanceGroupBind* groupBind = NULL; Group* group = player->GetGroup(); // use the player's difficulty setting (it may not be the same as the group's) if (group) { groupBind = group->GetBoundInstance(this); if (groupBind) pSave = groupBind->save; } } if (pSave) { // solo/perm/group newInstanceId = pSave->GetInstanceId(); map = FindInstanceMap(newInstanceId); // it is possible that the save exists but the map doesn't if (!map) map = CreateInstance(newInstanceId, pSave, pSave->GetDifficultyID()); } else { // if no instanceId via group members or instance saves is found // the instance will be created for the first time newInstanceId = sMapMgr->GenerateInstanceId(); Difficulty diff = player->GetGroup() ? player->GetGroup()->GetDifficultyID(GetEntry()) : player->GetDifficultyID(GetEntry()); //Seems it is now possible, but I do not know if it should be allowed //ASSERT(!FindInstanceMap(NewInstanceId)); map = FindInstanceMap(newInstanceId); if (!map) map = CreateInstance(newInstanceId, NULL, diff); } } else { newInstanceId = player->GetGUID().GetCounter(); map = FindInstanceMap(newInstanceId); if (!map) map = CreateGarrison(newInstanceId, player); } return map; }
/* - return the right instance for the object, based on its InstanceId - create the instance if it's not created already - the player is not actually added to the instance (only in InstanceMap::Add) */ Map* MapInstanced::CreateInstanceForPlayer(const uint32 mapId, Player* player, uint32 loginInstanceId) { if (GetId() != mapId || !player) return nullptr; Map* map = nullptr; uint32 newInstanceId = 0; // instanceId of the resulting map if (IsBattlegroundOrArena()) { // instantiate or find existing bg map for player // the instance id is set in battlegroundid newInstanceId = player->GetBattlegroundId(); if (!newInstanceId) return nullptr; map = sMapMgr->FindMap(mapId, newInstanceId); if (!map) { if (Battleground* bg = player->GetBattleground()) map = CreateBattleground(newInstanceId, bg); else { player->TeleportToBGEntryPoint(); return nullptr; } } } else if (!IsGarrison()) { InstancePlayerBind* pBind = player->GetBoundInstance(GetId(), player->GetDifficultyID(GetEntry())); InstanceSave* pSave = pBind ? pBind->save : nullptr; // priority: // 1. player's permanent bind // 2. player's current instance id if this is at login // 3. group's current bind // 4. player's current bind if (!pBind || !pBind->perm) { if (loginInstanceId) // if the player has a saved instance id on login, we either use this instance or relocate him out (return null) { map = FindInstanceMap(loginInstanceId); return (map && map->GetId() == GetId()) ? map : nullptr; // is this check necessary? or does MapInstanced only find instances of itself? } InstanceGroupBind* groupBind = nullptr; Group* group = player->GetGroup(); // use the player's difficulty setting (it may not be the same as the group's) if (group) { groupBind = group->GetBoundInstance(this); if (groupBind) { // solo saves should be reset when entering a group's instance player->UnbindInstance(GetId(), player->GetDifficultyID(GetEntry())); pSave = groupBind->save; } } } if (pSave) { // solo/perm/group newInstanceId = pSave->GetInstanceId(); map = FindInstanceMap(newInstanceId); // it is possible that the save exists but the map doesn't if (!map) map = CreateInstance(newInstanceId, pSave, pSave->GetDifficultyID(), player->GetTeamId()); } else { // if no instanceId via group members or instance saves is found // the instance will be created for the first time newInstanceId = sMapMgr->GenerateInstanceId(); Difficulty diff = player->GetGroup() ? player->GetGroup()->GetDifficultyID(GetEntry()) : player->GetDifficultyID(GetEntry()); //Seems it is now possible, but I do not know if it should be allowed //ASSERT(!FindInstanceMap(NewInstanceId)); map = FindInstanceMap(newInstanceId); if (!map) map = CreateInstance(newInstanceId, NULL, diff, player->GetTeamId()); } } else { newInstanceId = player->GetGUID().GetCounter(); map = FindInstanceMap(newInstanceId); if (!map) map = CreateGarrison(newInstanceId, player); } return map; }