/* * Ascent MMORPG Server * Copyright (C) 2005-2007 Ascent Team * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * */ #include "StdAfx.h" initialiseSingleton( InstanceSavingManagement ); //++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // Instance Saving Management //++++++++++++++++++++++++++++++++++++++++++++++++++++++++ InstanceSavingManagement::InstanceSavingManagement() { } InstanceSavingManagement::~InstanceSavingManagement() { InstanceInfo::const_iterator itr; for (itr = mInstanceInfoList.begin();itr != mInstanceInfoList.end(); itr++) { Instance_Map_Info_Holder *p = itr->second; delete p; } mInstanceInfoList.clear(); map::iterator itr2; for (itr2 = inactiveInstances.begin();itr2 != inactiveInstances.end(); itr2++) { InactiveInstance *p = itr2->second; delete p; } inactiveInstances.clear(); } void InstanceSavingManagement::BuildSavedInstancesForPlayer(Player *pPlayer) { bool result = false; bool hasBeenSaved = false; WorldPacket data; instanceInfoListMutex.Acquire(); InstanceInfo::const_iterator itr; for (itr = mInstanceInfoList.begin();itr != mInstanceInfoList.end(); itr++) { Instance_Map_Info_Holder *p = itr->second; result = p->FindPlayer(pPlayer->GetGUID(), (uint32)NULL, MODE_NORMAL); //find only non grouped results if(result) { data.Initialize(SMSG_INSTANCE_SAVE); data << uint32(itr->first); pPlayer->GetSession()->SendPacket(&data); data.Initialize(SMSG_INSTANCE_RESET_ACTIVATE); data << uint32(0x01); pPlayer->GetSession()->SendPacket(&data); hasBeenSaved = true; } } instanceInfoListMutex.Release(); if(!hasBeenSaved) { data.Initialize(SMSG_INSTANCE_RESET_ACTIVATE); data << uint32(0x00); pPlayer->GetSession()->SendPacket(&data); } } Instance_Map_Info_Holder *InstanceSavingManagement::SaveInstance(MapMgr *pInstance) { ASSERT( pInstance->GetInstanceID() ); instanceInfoListMutex.Acquire(); InstanceInfo::iterator itr = mInstanceInfoList.find( pInstance->GetMapId() ); if(itr == mInstanceInfoList.end()) { Instance_Map_Info_Holder *mapholder; mapholder = new Instance_Map_Info_Holder; mapholder->SetMapInfo(pInstance->GetMapInfo()); mapholder->AddInstanceId(pInstance); mInstanceInfoList[pInstance->GetMapId()] = mapholder; instanceInfoListMutex.Release(); return mapholder; } else { Instance_Map_Info_Holder *mapholder = itr->second; mapholder->SetMapInfo(pInstance->GetMapInfo()); mapholder->AddInstanceId(pInstance); instanceInfoListMutex.Release(); return mapholder; } instanceInfoListMutex.Release(); return NULL; } void InstanceSavingManagement::SavePlayerToInstance(Player *pPlayer, uint32 mapid) { WorldPacket data; instanceInfoListMutex.Acquire(); InstanceInfo::iterator itr = mInstanceInfoList.find( mapid ); if(itr != mInstanceInfoList.end()) { bool result = itr->second->FindPlayer(pPlayer->GetGUID(), (pPlayer->InGroup() ? pPlayer->GetGroup()->GetID() : 0), pPlayer->iInstanceType); if(result) { instanceInfoListMutex.Release(); return; } else { if(pPlayer->GetInstanceID()) //check if player is really on a instanceid { if(itr->second->GetMapInfo() && itr->second->GetMapInfo()->type == INSTANCE_RAID || itr->second->GetMapInfo() && itr->second->GetMapInfo()->type == INSTANCE_MULTIMODE && pPlayer->iInstanceType == MODE_HEROIC) { itr->second->AddPlayer(pPlayer->GetGUID(), pPlayer->GetInstanceID()); sChatHandler.SystemMessageToPlr(pPlayer,"You are now saved to this instance."); } else { itr->second->AddPlayer(pPlayer->GetGUID(), pPlayer->GetInstanceID()); } if(!pPlayer->InGroup()) { data.Initialize(SMSG_INSTANCE_SAVE); data << mapid; pPlayer->GetSession()->SendPacket(&data); data.Initialize(SMSG_INSTANCE_RESET_ACTIVATE); data << uint32(0x01); pPlayer->GetSession()->SendPacket(&data); } } } } instanceInfoListMutex.Release(); } void InstanceSavingManagement::ResetSavedInstancesForPlayer(Player *pPlayer) { bool result; WorldPacket data; instanceInfoListMutex.Acquire(); InstanceInfo::const_iterator itr; for (itr = mInstanceInfoList.begin();itr != mInstanceInfoList.end(); itr++) { Instance_Map_Info_Holder *p = itr->second; MapInfo *pMapInfo = p->GetMapInfo(); if(pMapInfo->type == INSTANCE_RAID) continue; if(pPlayer->InGroup()) result = p->RemoveGroup(pPlayer->GetGroup()->GetID()); else result = p->RemovePlayer(pPlayer->GetGUID()); if(result) { data.Initialize(SMSG_RESET_INSTANCE); data << itr->first; pPlayer->GetSession()->SendPacket(&data); } } instanceInfoListMutex.Release(); } void InstanceSavingManagement::RemoveSavedInstance(uint32 mapid, uint32 instanceid, bool bHardReset) { //my concept: while the real instance data is deleted from worldcreator, the player saving remain until the real //reset comes from MapMgr wich should be a "ghost" map by then without players going in or out. //why is this? simple, due to players be abling to reset their instance saving. this method is more safe to avoid conflits //or worse :P bugs. //Guard guard(_busy); ASSERT( mapid ); ASSERT( instanceid ); instanceInfoListMutex.Acquire(); InstanceInfo::iterator itr = mInstanceInfoList.find( mapid ); if(itr != mInstanceInfoList.end()) { Instance_Map_Info_Holder *p1 = itr->second; MapInfo * pMapInfo = WorldMapInfoStorage.LookupEntry(mapid); if(!pMapInfo) { instanceInfoListMutex.Release(); return; } if(bHardReset && pMapInfo && pMapInfo->type == INSTANCE_RAID || bHardReset && pMapInfo && pMapInfo->type == INSTANCE_MULTIMODE) { p1->RemoveInstanceId(instanceid); DeleteInstanceFromDB(instanceid); } else if(!bHardReset && pMapInfo && pMapInfo->type != INSTANCE_RAID && pMapInfo->type != INSTANCE_MULTIMODE ) { p1->RemoveInstanceId(instanceid); } } instanceInfoListMutex.Release(); } //++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // Description: Detects if a player is saved or not inside a specific mapid // Note: This can be only used for Instances that have a lockout system like heroic and raid instances. // Otherwise this function doesnt know if it should search for group or solo instances. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++ bool InstanceSavingManagement::IsPlayerSavedToMap(uint32 mapid, Player *pPlayer) { instanceInfoListMutex.Acquire(); InstanceInfo::iterator itr = mInstanceInfoList.find( mapid ); if(itr != mInstanceInfoList.end()) { Instance_Map_Info_Holder *p = itr->second; MapInfo *pMapInfo = p->GetMapInfo(); if(pMapInfo && pMapInfo->type == INSTANCE_RAID || pMapInfo && pMapInfo->type == INSTANCE_MULTIMODE) { bool result = p->FindPlayer(pPlayer->GetGUID(), (uint32)NULL, pPlayer->iInstanceType); if(result) { instanceInfoListMutex.Release(); return true; } } } instanceInfoListMutex.Release(); return false; } bool InstanceSavingManagement::IsPlayerSavedToInstanceId(uint32 mapid, uint32 instanceid, Player *pPlayer) { instanceInfoListMutex.Acquire(); InstanceInfo::iterator itr = mInstanceInfoList.find( mapid ); if(itr != mInstanceInfoList.end()) { Instance_Map_Info_Holder *p = itr->second; if(p->GetMapInfo() && p->GetMapInfo()->type == INSTANCE_RAID || p->GetMapInfo() && p->GetMapInfo()->type == INSTANCE_MULTIMODE) { bool result = p->IsPlayerSavedToInstanceId(pPlayer->GetGUID(), instanceid); if(result) { instanceInfoListMutex.Release(); return true; } } } instanceInfoListMutex.Release(); return false; } void InstanceSavingManagement::LoadSavedInstances() { QueryResult *result = NULL; result = CharacterDatabase.Query("SELECT * FROM instances"); if(result==NULL) { return; } do { Field *fields = result->Fetch(); // check for instance expiry if((uint32)time(NULL) >= fields[5].GetUInt32()) { CharacterDatabase.Execute("DELETE FROM instances WHERE instanceid = %u", fields[0].GetUInt32()); continue; } // Inactive instance data saving system added InactiveInstance * ia = new InactiveInstance; ia->InstanceId = fields[0].GetUInt32(); ia->MapId = fields[1].GetUInt32(); ia->Creation = fields[4].GetUInt32(); ia->ExpireTime = fields[5].GetUInt32(); ia->difficulty = fields[6].GetUInt32(); sInstanceSavingManager.AddInactiveInstance(ia); sInstanceSavingManager.SaveInstance(ia); sInstanceSavingManager.RepopulateSavedData(fields[1].GetUInt32(), fields[0].GetUInt32(), fields[2].GetString(), fields[3].GetString()); } while( result->NextRow() ); Log.Notice("InstanceSaveMgr", "%u saved instances loaded.", result->GetRowCount()); delete result; } void InstanceSavingManagement::RepopulateSavedData(uint32 mapid, uint32 instanceid, const char *cNpc, const char *cPlayer) { std::string ndata = cPlayer; std::string::size_type last_pos = 0, pos = 0; uint64 val = 0; uint32 val2 = 0; InstanceInfo::iterator itr = mInstanceInfoList.find( mapid ); if(itr != mInstanceInfoList.end()) { Instance_Map_Info_Holder *p = itr->second; Instance_Map_InstanceId_Holder *pi = p->GetInstanceId(instanceid); if(pi) { pi->ClearAllPlayers(); do { pos = ndata.find(" ", last_pos); if(pos == std::string::npos) { break; } sscanf(ndata.substr(last_pos, (pos-last_pos)).c_str(), I64FMTD, &val); last_pos = pos+1; if(val) pi->AddPlayer(val); } while(pos != std::string::npos); last_pos = 0, pos = 0, val = 0; ndata = cNpc; pi->ClearAllObjects(); do { pos = ndata.find(" ", last_pos); if(pos == std::string::npos) { break; } val2 = atol(ndata.substr(last_pos, (pos-last_pos)).c_str()); last_pos = pos+1; if(val2) pi->AddObject(val2); } while(pos != std::string::npos); } } } void InstanceSavingManagement::SaveInstanceIdToDB(uint32 instanceid, uint32 mapid) { instanceInfoListMutex.Acquire(); InstanceInfo::iterator itr = mInstanceInfoList.find( mapid ); if(itr != mInstanceInfoList.end()) { Instance_Map_Info_Holder *p = itr->second; Instance_Map_InstanceId_Holder *pi = p->GetInstanceId(instanceid); if(pi) { pi->SaveInstanceToDB(); } } instanceInfoListMutex.Release(); } void InstanceSavingManagement::SaveObjectStateToInstance(Unit *pUnit) { instanceInfoListMutex.Acquire(); InstanceInfo::iterator itr = mInstanceInfoList.find( pUnit->GetMapId() ); if(itr != mInstanceInfoList.end()) { Instance_Map_Info_Holder *p = itr->second; Instance_Map_InstanceId_Holder *pi = p->GetInstanceId(pUnit->GetInstanceID()); if(pi) { pi->AddObject(static_cast(pUnit)->GetSQL_id()); } } instanceInfoListMutex.Release(); } Instance_Map_InstanceId_Holder *InstanceSavingManagement::GetInstance(uint32 mapid, uint32 instanceid) { instanceInfoListMutex.Acquire(); InstanceInfo::iterator itr = mInstanceInfoList.find( mapid ); if(itr != mInstanceInfoList.end()) { Instance_Map_Info_Holder *p = itr->second; Instance_Map_InstanceId_Holder *pi = p->GetInstanceId(instanceid); if(pi) { instanceInfoListMutex.Release(); return pi; } } instanceInfoListMutex.Release(); return NULL; } Instance_Map_InstanceId_Holder *InstanceSavingManagement::GetRaidAndMMInstance(uint32 mapid, Player * pPlayer) { instanceInfoListMutex.Acquire(); InstanceInfo::iterator itr = mInstanceInfoList.find( mapid ); if(itr != mInstanceInfoList.end()) { Instance_Map_Info_Holder *p = itr->second; if(p->GetMapInfo() && p->GetMapInfo()->type == INSTANCE_RAID || p->GetMapInfo() && p->GetMapInfo()->type == INSTANCE_MULTIMODE) { Instance_Map_InstanceId_Holder *pi = p->getInstanceIdByPlayer(pPlayer->GetGUID(), pPlayer->iInstanceType); if(pi) { instanceInfoListMutex.Release(); return pi; } } } instanceInfoListMutex.Release(); return NULL; } void InstanceSavingManagement::BuildRaidSavedInstancesForPlayer(Player *pPlayer) { /*hmm packet structure for this one? counter, mapid time instanceid */ WorldPacket data; uint32 counter = 0; data.Initialize(SMSG_RAID_INSTANCE_INFO); instanceInfoListMutex.Acquire(); InstanceInfo::const_iterator itr; for (itr = mInstanceInfoList.begin();itr != mInstanceInfoList.end(); itr++) { Instance_Map_Info_Holder *p = itr->second; if(p->GetMapInfo() && p->GetMapInfo()->type == INSTANCE_RAID || p->GetMapInfo() && p->GetMapInfo()->type == INSTANCE_MULTIMODE) { Instance_Map_InstanceId_Holder *pi = p->getInstanceIdByPlayer(pPlayer->GetGUID(), pPlayer->iInstanceType, true); if(pi) { data << uint32(0x00); data << (p->GetMapInfo() ? p->GetMapInfo()->mapid : 0); data << (uint32)(pi->GetRaidExpireTime() - time(NULL)); data << pi->GetInstanceID(); counter++; } } } instanceInfoListMutex.Release(); data.wpos(0); data << counter; pPlayer->GetSession()->SendPacket(&data); } void InstanceSavingManagement::DeleteInstanceFromDB(uint32 instanceid) { std::stringstream ss; ss << "DELETE FROM instances WHERE instanceid = '"; ss << instanceid << "'"; CharacterDatabase.Execute( ss.str().c_str() ); } //++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // Instance Management - MapID InstanceId list holder //++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Instance_Map_Info_Holder::Instance_Map_Info_Holder() { m_pMapInfo = NULL; } Instance_Map_Info_Holder::~Instance_Map_Info_Holder() { //clear all instanceids inside this mapid InstanceIdList::const_iterator itr; for (itr = mInstanceIdList.begin();itr != mInstanceIdList.end(); itr++) { Instance_Map_InstanceId_Holder *p = itr->second; delete p; } mInstanceIdList.clear(); } void Instance_Map_Info_Holder::RemoveInstanceId(uint32 instanceid) { instanceIdListMutex.Acquire(); InstanceIdList::iterator itr = mInstanceIdList.find( instanceid ); if(itr != mInstanceIdList.end()) { delete itr->second; mInstanceIdList.erase(itr); } instanceIdListMutex.Release(); } Instance_Map_InstanceId_Holder *Instance_Map_Info_Holder::GetInstanceId(uint32 instanceid) { instanceIdListMutex.Acquire(); InstanceIdList::iterator itr = mInstanceIdList.find( instanceid ); if(itr != mInstanceIdList.end()) { instanceIdListMutex.Release(); return itr->second; } instanceIdListMutex.Release(); return NULL; } void Instance_Map_Info_Holder::AddInstanceId(MapMgr *pInstance) { ASSERT( pInstance->GetInstanceID() ); instanceIdListMutex.Acquire(); InstanceIdList::iterator itr = mInstanceIdList.find( pInstance->GetInstanceID() ); if(itr == mInstanceIdList.end()) { Instance_Map_InstanceId_Holder *pIdList; pIdList = new Instance_Map_InstanceId_Holder; pIdList->SetMapInfo(pInstance->GetMapInfo()); pIdList->SetCreationTime(pInstance->CreationTime); pIdList->SetRaidExpireTime(pInstance->RaidExpireTime); pIdList->SetInstanceID(pInstance->GetInstanceID()); pIdList->SetDifficulty(pInstance->iInstanceMode); pIdList->SetGroupSignature(pInstance->GetGroupSignature()); //allows multiple instanceids per mapid mInstanceIdList[pInstance->GetInstanceID()] = pIdList; } instanceIdListMutex.Release(); } void Instance_Map_Info_Holder::AddInstanceId(InactiveInstance * ia) { ASSERT( ia->InstanceId ); instanceIdListMutex.Acquire(); InstanceIdList::iterator itr = mInstanceIdList.find( ia->InstanceId ); if(itr == mInstanceIdList.end()) { Instance_Map_InstanceId_Holder *pIdList; pIdList = new Instance_Map_InstanceId_Holder; MapInfo *pMapInfo = WorldMapInfoStorage.LookupEntry(ia->MapId); ASSERT(pMapInfo); //if this asserts then something went rly wrong. pIdList->SetMapInfo(pMapInfo); pIdList->SetCreationTime(ia->Creator); pIdList->SetRaidExpireTime(ia->ExpireTime); pIdList->SetInstanceID(ia->InstanceId); pIdList->SetDifficulty(ia->difficulty); mInstanceIdList[ia->InstanceId] = pIdList; } instanceIdListMutex.Release(); } void Instance_Map_Info_Holder::AddPlayer(uint64 guid, uint32 InstanceID) { ASSERT( InstanceID ); instanceIdListMutex.Acquire(); InstanceIdList::iterator itr = mInstanceIdList.find( InstanceID ); if(itr != mInstanceIdList.end()) { Instance_Map_InstanceId_Holder *p = itr->second; p->AddPlayer(guid); } instanceIdListMutex.Release(); } bool Instance_Map_Info_Holder::RemovePlayer(uint64 guid, uint32 InstanceID) { ASSERT( InstanceID ); bool result = false; instanceIdListMutex.Acquire(); InstanceIdList::iterator itr = mInstanceIdList.find( InstanceID ); if(itr != mInstanceIdList.end()) { Instance_Map_InstanceId_Holder *p = itr->second; result = p->RemovePlayer(guid); instanceIdListMutex.Release(); return result; } instanceIdListMutex.Release(); return false; } bool Instance_Map_Info_Holder::RemovePlayer(uint64 guid) { bool result = false; bool result2 = false; instanceIdListMutex.Acquire(); InstanceIdList::iterator itr, itr2; for (itr = mInstanceIdList.begin();itr != mInstanceIdList.end();) { itr2 = itr; ++itr; Instance_Map_InstanceId_Holder *p = itr2->second; MapMgr * mapMgr = sWorldCreator.ISMGetInstanceBeforeRemoval(itr2->first, GetMapInfo()->mapid, true); if(mapMgr) { // dont reset an instnace with players inside.. dunno how they got in there anyway :P if(mapMgr->HasPlayers()) { Player * pPlayer = objmgr.GetPlayer(guid); if(pPlayer) sChatHandler.SystemMessageToPlr(pPlayer,"You are trying to reset a instance when there are still players inside"); instanceIdListMutex.Release(); return false; } } if(!p->GetGroupSignature() && GetMapInfo()->type != INSTANCE_RAID && p->GetDifficulty() != MODE_HEROIC) //only resets solo instances { result = p->RemovePlayer(guid); if(result) { sWorldCreator.DeleteInstance(itr2->first, m_pMapInfo->mapid); delete p; sLog.outDebug("Removing instance from the itr\n"); mInstanceIdList.erase(itr2); result2 = true; continue; } } } instanceIdListMutex.Release(); return result2; } bool Instance_Map_Info_Holder::RemoveGroup(uint32 iGroupSignature) { bool result = false; bool result2 = false; instanceIdListMutex.Acquire(); InstanceIdList::iterator itr, itr2; for (itr = mInstanceIdList.begin();itr != mInstanceIdList.end();) { itr2 = itr; ++itr; Instance_Map_InstanceId_Holder *p = itr2->second; if(p->GetGroupSignature() && p->GetGroupSignature() == iGroupSignature) //only resets this group instance ids { MapMgr * mapMgr = sWorldCreator.ISMGetInstanceBeforeRemoval(itr2->first, GetMapInfo()->mapid, true); if(mapMgr) { // dont reset an instnace with players inside.. dunno how they got in there anyway :P if(mapMgr->HasPlayers()) { Group *pGroup = objmgr.GetGroupById(iGroupSignature); if(pGroup) { Player * pPlayer = pGroup->GetLeader(); if(pPlayer) sChatHandler.SystemMessageToPlr(pPlayer,"You are trying to reset a instance when there are still players inside"); } instanceIdListMutex.Release(); return false; } } if(p->GetDifficulty() == MODE_HEROIC || p->GetMapInfo()->type == INSTANCE_RAID) { continue; } result = p->ClearAllPlayers(); if(result) { sWorldCreator.DeleteInstance(itr2->first, m_pMapInfo->mapid); delete p; sLog.outDebug("Removing group instance from the itr\n"); mInstanceIdList.erase(itr2); result2 = true; continue; } } } instanceIdListMutex.Release(); return result2; } bool Instance_Map_Info_Holder::FindPlayer(uint64 guid, uint32 iGroupSignature, uint32 difficulty) { instanceIdListMutex.Acquire(); InstanceIdList::const_iterator itr; for (itr = mInstanceIdList.begin();itr != mInstanceIdList.end(); itr++) { Instance_Map_InstanceId_Holder *p = itr->second; // group matches, returns false and breaks loop if it fails // cant exist 2 groups with same id so no point in continue loop // raid groups are ignored for this check. MapInfo *pMapInfo = GetMapInfo(); if(!pMapInfo) continue; //this should never happen rly. if(iGroupSignature && pMapInfo->type != INSTANCE_RAID || iGroupSignature && pMapInfo->type == INSTANCE_MULTIMODE && p->GetDifficulty() == MODE_NORMAL && difficulty == MODE_NORMAL) { if(p->GetGroupSignature() == iGroupSignature) { bool result = p->FindPlayer(guid); if(result) { instanceIdListMutex.Release(); return true; } instanceIdListMutex.Release(); return false; } } else { if(p->GetDifficulty() == difficulty) { bool result = p->FindPlayer(guid); if(result) { instanceIdListMutex.Release(); return true; } } } } instanceIdListMutex.Release(); return false; } bool Instance_Map_Info_Holder::IsPlayerSavedToInstanceId(uint64 guid, uint32 instanceid) { instanceIdListMutex.Acquire(); InstanceIdList::const_iterator itr = mInstanceIdList.find( instanceid ); if(itr != mInstanceIdList.end()) { Instance_Map_InstanceId_Holder *p = itr->second; if(p->GetInstanceID() == instanceid) { bool result = p->FindPlayer(guid); if(result) { instanceIdListMutex.Release(); return true; } } } instanceIdListMutex.Release(); return false; } Instance_Map_InstanceId_Holder *Instance_Map_Info_Holder::getInstanceIdByPlayer(uint64 guid, uint32 difficulty, bool iIgnoreDifficulty) { instanceIdListMutex.Acquire(); InstanceIdList::const_iterator itr; for (itr = mInstanceIdList.begin();itr != mInstanceIdList.end(); itr++) { Instance_Map_InstanceId_Holder *p = itr->second; if(iIgnoreDifficulty) { if(p->FindPlayer(guid)) { instanceIdListMutex.Release(); return p; } } else { if(p->FindPlayer(guid) && p->GetDifficulty() == difficulty) { instanceIdListMutex.Release(); return p; } } } instanceIdListMutex.Release(); return NULL; } //++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // Instance Management - InstanceId player list holder //++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Instance_Map_InstanceId_Holder::Instance_Map_InstanceId_Holder() { m_pMapInfo = NULL; CreationTime = 0; ExpireTime = 0; IsSaved = false; m_instanceid = 0; difficulty = MODE_NORMAL; } Instance_Map_InstanceId_Holder::~Instance_Map_InstanceId_Holder() { mPlayerList.clear(); mNpcList.clear(); } bool Instance_Map_InstanceId_Holder::FindPlayer(uint64 guid) { playerListMutex.Acquire(); PlayerList::iterator itr = mPlayerList.find( guid ); if(itr == mPlayerList.end()) { playerListMutex.Release(); return false; } else { playerListMutex.Release(); return true; } } bool Instance_Map_InstanceId_Holder::ClearAllPlayers() { playerListMutex.Acquire(); mPlayerList.clear(); playerListMutex.Release(); return true; } bool Instance_Map_InstanceId_Holder::ClearAllObjects() { npcListMutex.Acquire(); mNpcList.clear(); npcListMutex.Release(); return true; } void Instance_Map_InstanceId_Holder::AddPlayer(uint64 guid) { playerListMutex.Acquire(); mPlayerList[guid] = guid; playerListMutex.Release(); } void Instance_Map_InstanceId_Holder::AddObject(uint32 entry) { npcListMutex.Acquire(); mNpcList[entry] = entry; npcListMutex.Release(); } bool Instance_Map_InstanceId_Holder::FindObject(uint32 entry) { npcListMutex.Acquire(); NpcList::iterator itr = mNpcList.find( entry ); if(itr == mNpcList.end()) { npcListMutex.Release(); return false; } else { npcListMutex.Release(); return true; } } bool Instance_Map_InstanceId_Holder::RemovePlayer(uint64 guid) { playerListMutex.Acquire(); PlayerList::iterator itr = mPlayerList.find( guid ); if(itr == mPlayerList.end()) { //error playerListMutex.Release(); return false; } else { mPlayerList.erase(itr); playerListMutex.Release(); return true; } } void Instance_Map_InstanceId_Holder::SaveInstanceToDB() { std::stringstream ss; PlayerList::const_iterator itr; ss << "REPLACE INTO instances VALUES ("; ss << m_instanceid << ", "; ss << GetMapInfo()->mapid << ", '"; npcListMutex.Acquire(); for (itr = mNpcList.begin();itr != mNpcList.end(); itr++) { ss << itr->first << " "; } npcListMutex.Release(); ss << "', '"; playerListMutex.Acquire(); for (itr = mPlayerList.begin();itr != mPlayerList.end(); itr++) { ss << itr->first << " "; } playerListMutex.Release(); ss << "', "; ss << CreationTime << ", "; ss << ExpireTime << ", "; ss << difficulty << ");"; CharacterDatabase.Execute( ss.str().c_str() ); } void InstanceSavingManagement::AddInactiveInstance(InactiveInstance * ia) { inactiveInstancesMutex.Acquire(); inactiveInstances[ia->InstanceId] = ia; inactiveInstancesMutex.Release(); } void InstanceSavingManagement::RemoveSavedInstance(uint32 instance_id) { inactiveInstancesMutex.Acquire(); map::iterator itr = inactiveInstances.find(instance_id); if(itr == inactiveInstances.end()) { inactiveInstancesMutex.Release(); return; } delete itr->second; inactiveInstances.erase(itr); inactiveInstancesMutex.Release(); } void InstanceSavingManagement::CreateInactiveInstance(MapMgr * mgr) { // called on mapmgr expire.. InactiveInstance * ia = new InactiveInstance; ia->Creation = mgr->CreationTime; ia->InstanceId = mgr->GetInstanceID(); ia->MapId = mgr->GetMapId(); ia->Creator = mgr->GetCreator(); ia->GroupSignature = mgr->GetGroupSignature(); ia->difficulty = mgr->iInstanceMode; AddInactiveInstance(ia); } InactiveInstance * InstanceSavingManagement::GetInactiveInstance(uint32 instance_id) { inactiveInstancesMutex.Acquire(); map::iterator itr = inactiveInstances.find(instance_id); if(itr == inactiveInstances.end()) { inactiveInstancesMutex.Release(); return 0; } InactiveInstance * ia = itr->second; inactiveInstances.erase(itr); inactiveInstancesMutex.Release(); return ia; } void InstanceSavingManagement::SaveInstance(InactiveInstance *ia) { ASSERT( ia->InstanceId ); inactiveInstancesMutex.Acquire(); InstanceInfo::iterator itr = mInstanceInfoList.find( ia->MapId ); if(itr == mInstanceInfoList.end()) { Instance_Map_Info_Holder *mapholder; mapholder = new Instance_Map_Info_Holder; MapInfo *pMapInfo = WorldMapInfoStorage.LookupEntry(ia->MapId); if(!pMapInfo) { inactiveInstancesMutex.Release(); return; } mapholder->SetMapInfo(pMapInfo); mapholder->AddInstanceId(ia); mInstanceInfoList[ia->MapId] = mapholder; } else { Instance_Map_Info_Holder *mapholder = itr->second; MapInfo *pMapInfo = WorldMapInfoStorage.LookupEntry(ia->MapId); if(!pMapInfo) { inactiveInstancesMutex.Release(); return; } mapholder->SetMapInfo(pMapInfo); mapholder->AddInstanceId(ia); } inactiveInstancesMutex.Release(); }