Example #1
0
MapMgr* InstanceMgr::GetInstance(uint32 MapId, uint32 InstanceId)
{
	Instance * in;
	InstanceMap::iterator itr;
	InstanceMap * instancemap;
	MapInfo * inf = WorldMapInfoStorage.LookupEntry(MapId);

	// we can *never* teleport to maps without a mapinfo.
	if( inf == NULL || MapId >= NUM_MAPS )
		return NULLMAPMGR;


	// single-instance maps never go into the instance set.
	if( inf->type == INSTANCE_NULL )
		return m_singleMaps[MapId];

	m_mapLock.Acquire();
	instancemap = m_instances[MapId];
	if(instancemap != NULL)
	{
		// check our saved instance id. see if its valid, and if we can join before trying to find one.
		itr = instancemap->find(InstanceId);
		if(itr != instancemap->end())
		{
			if(itr->second->m_mapMgr)
			{
				m_mapLock.Release();
				return itr->second->m_mapMgr;
			}
		}

		// iterate over our instances, and see if any of them are owned/joinable by him.
		for(itr = instancemap->begin(); itr != instancemap->end();)
		{
			in = itr->second;
			++itr;

			// this is our instance.
			if(in->m_mapMgr == NULL)
			{
				// create the actual instance.
				in->m_mapMgr = _CreateInstance(in);
				m_mapLock.Release();
				return in->m_mapMgr;
			}
			else
			{
				// instance is already created.
				m_mapLock.Release();
				return in->m_mapMgr;
			}
		}
	}

	// if we're here, it means there are no instances on that map, or none of the instances on that map are joinable
	// by this player.
	m_mapLock.Release();
	return NULLMAPMGR;
}
Example #2
0
void InstanceMgr::_CreateMap(uint32 mapid)
{
	if( mapid >= NUM_MAPS )
		return;

	MapInfo* inf = WorldMapInfoStorage.LookupEntry(mapid);
	if(!inf || m_maps[mapid])
		return;

	m_maps[mapid] = new Map(mapid, inf);
	if(inf->type == INSTANCE_NULL)
	{
		// we're a continent, create the instance.
		_CreateInstance(mapid, GenerateInstanceID());
	}
}
Example #3
0
void InstanceMgr::_CreateMap(uint32 mapid)
{
    if (mapid >= NUM_MAPS)
        return;

    MapInfo const* inf = sMySQLStore.GetWorldMapInfo(mapid);
    if (inf == nullptr)
        return;

    if (m_maps[mapid] != NULL)
        return;

    m_maps[mapid] = new Map(mapid, inf);
    if (inf->type == INSTANCE_NULL)
    {
        // we're a continent, create the instance.
        _CreateInstance(mapid, GenerateInstanceID());
    }
}
Example #4
0
MapMgr* InstanceMgr::GetInstance(Object* obj)
{
	Player* plr;
	Instance* in;
	InstanceMap::iterator itr;
	InstanceMap* instancemap;
	MapInfo* inf = WorldMapInfoStorage.LookupEntry(obj->GetMapId());

	// we can *never* teleport to maps without a mapinfo.
	if(inf == NULL || obj->GetMapId() >= NUM_MAPS)
		return NULL;

	if(obj->IsPlayer())
	{
		// players can join instances based on their groups/solo status.
		plr = TO< Player* >(obj);

		// single-instance maps never go into the instance set.
		if(inf->type == INSTANCE_NULL)
			return m_singleMaps[obj->GetMapId()];

		m_mapLock.Acquire();
		instancemap = m_instances[obj->GetMapId()];
		if(instancemap != NULL)
		{
			// check our saved instance id. see if its valid, and if we can join before trying to find one.
			itr = instancemap->find(obj->GetInstanceID());
			if(itr != instancemap->end())
			{
				if(itr->second->m_mapMgr == NULL)
				{
					itr->second->m_mapMgr = _CreateInstance(itr->second);
				}
				if(itr->second->m_mapMgr)
				{
					m_mapLock.Release();
					return itr->second->m_mapMgr;
				}
			}

			// iterate over our instances, and see if any of them are owned/joinable by him.
			for(itr = instancemap->begin(); itr != instancemap->end();)
			{
				in = itr->second;
				++itr;

				uint32 difficulty;

				if(in->m_mapInfo->type == INSTANCE_RAID)
					difficulty = plr->GetRaidDifficulty();
				else
					difficulty = plr->GetDungeonDifficulty();

				if(in->m_difficulty == difficulty && PlayerOwnsInstance(in, plr))
				{
					// this is our instance.
					if(in->m_mapMgr == NULL)
					{
						/*if(plr->m_TeleportState == 1)
						{
							// the player is loading. boot him out to the entry point, we don't want to spam useless instances on startup.
							m_mapLock.Release();
							return NULL;
						}*/

						// create the actual instance.
						in->m_mapMgr = _CreateInstance(in);
						m_mapLock.Release();
						return in->m_mapMgr;
					}
					else
					{
						// instance is already created.
						m_mapLock.Release();
						return in->m_mapMgr;
					}
				}
			}
		}

		// if we're here, it means there are no instances on that map, or none of the instances on that map are joinable
		// by this player.
		m_mapLock.Release();
		return NULL;
	}
	else
	{
		// units are *always* limited to their set instance ids.
		if(inf->type == INSTANCE_NULL)
			return m_singleMaps[obj->GetMapId()];

		m_mapLock.Acquire();
		instancemap = m_instances[obj->GetMapId()];
		if(instancemap)
		{
			itr = instancemap->find(obj->GetInstanceID());
			if(itr != instancemap->end())
			{
				// we never create instances just for units.
				m_mapLock.Release();
				return itr->second->m_mapMgr;
			}
		}

		// instance is non-existent (shouldn't really happen for units...)
		m_mapLock.Release();
		return NULL;
	}
}
Example #5
0
MapMgr* InstanceMgr::GetInstance(Object* obj)
{
	Player* plr = NULL;
	InstanceMap::iterator itr;
	InstanceMap * instancemap = NULL;
	MapInfo * inf = NULL;
	inf = WorldMapInfoStorage.LookupEntry(obj->GetMapId());

	// we can *never* teleport to maps without a mapinfo.
	if( inf == NULL || obj->GetMapId() >= NUM_MAPS )
		return NULLMAPMGR;

	if( obj->IsPlayer() )
	{
		// players can join instances based on their groups/solo status.
		plr = TO_PLAYER( obj );

		// single-instance maps never go into the instance set.
		if( inf->type == INSTANCE_NULL )
			return m_singleMaps[obj->GetMapId()];

		m_mapLock.Acquire();
		instancemap = m_instances[obj->GetMapId()];
		if(instancemap != NULL)
		{
			// check our saved instance id. see if its valid, and if we can join before trying to find one.
			itr = instancemap->find(obj->GetInstanceID());
			if(itr != instancemap->end())
			{
				if(itr->second)
				{
					//we have an instance,but can we enter it?
					uint8 owns =  PlayerOwnsInstance( itr->second, plr );
					if( owns >= OWNER_CHECK_OK )
					{
						//wakeup call for saved instances
						if(itr->second->m_mapMgr == NULL)
							itr->second->m_mapMgr = _CreateInstance(itr->second);

						if(owns == OWNER_CHECK_SAVED_OK && !itr->second->m_mapMgr->HasPlayers())
						{
							if(plr->GetGroup())
								itr->second->m_creatorGroup = plr->GetGroupID();
						}
						m_mapLock.Release();
						return itr->second->m_mapMgr;
					}
				}
			}


			// iterate over our instances, and see if any of them are owned/joinable by him.
			for(itr = instancemap->begin(); itr != instancemap->end(); itr++)
			{
				// Is this our instance?
				uint8 owns = PlayerOwnsInstance(itr->second, plr);
				if(owns >= OWNER_CHECK_OK )
				{
					//wakeup call for saved instances
					if(itr->second->m_mapMgr == NULL)
						itr->second->m_mapMgr = _CreateInstance(itr->second);

					if(owns == OWNER_CHECK_SAVED_OK && !itr->second->m_mapMgr->HasPlayers())
					{
						if(plr->GetGroup())
							itr->second->m_creatorGroup = plr->GetGroupID();
					}
					m_mapLock.Release();
					return itr->second->m_mapMgr;
				}
				else
					DEBUG_LOG("InstanceMgr","Check failed %s", plr->GetName());
			}
		}

		// if we're here, it means there are no instances on that map, or none of the instances on that map are joinable
		// by this player.
		m_mapLock.Release();
		return NULLMAPMGR;
	}
	else
	{
		// units are *always* limited to their set instance ids.
		if(inf->type == INSTANCE_NULL)
			return m_singleMaps[obj->GetMapId()];

		m_mapLock.Acquire();
		instancemap = m_instances[obj->GetMapId()];
		if(instancemap != NULL)
		{
			itr = instancemap->find(obj->GetInstanceID());
			if(itr != instancemap->end())
			{
				// we never create instances just for units.
				m_mapLock.Release();
				return itr->second->m_mapMgr;
			}
		}

		// instance is non-existant (shouldn't really happen for units...)
		m_mapLock.Release();
		return NULLMAPMGR;
	}
}
Example #6
0
uint32 InstanceMgr::PreTeleport(uint32 mapid, Player* plr, uint32 instanceid)
{
	// preteleport is where all the magic happens :P instance creation, etc.
	MapInfo * inf = LimitedMapInfoStorage.LookupEntry(mapid);
	MapEntry* map = dbcMap.LookupEntry(mapid);
	InstanceMap * instancemap;
	Instance * in = NULL;

	//is the map vaild?
	if(inf == NULL || mapid >= NUM_MAPS)
		return INSTANCE_ABORT_NOT_FOUND;

	// main continent check.
	if(inf->type == INSTANCE_NULL) // we can check if the destination world server is online or not and then cancel them before they load.
		return (m_singleMaps[mapid] != NULL) ? INSTANCE_OK : INSTANCE_ABORT_NOT_FOUND;

	// shouldn't happen
	if(inf->type == INSTANCE_PVP)
		return INSTANCE_ABORT_NOT_FOUND;

	if(map->israid()) // check that heroic mode is available if the player has requested it.
	{
		if(plr->iRaidType > 1 && inf->type != INSTANCE_MULTIMODE)
			return INSTANCE_ABORT_HEROIC_MODE_NOT_AVAILABLE;
	}
	else if(plr->iInstanceType && inf->type != INSTANCE_MULTIMODE)
		return INSTANCE_ABORT_HEROIC_MODE_NOT_AVAILABLE;

	//do we need addition raid/heroic checks?
	Group * pGroup = plr->GetGroup() ;
	if( !plr->triggerpass_cheat )
	{
		// players without groups cannot enter raid instances (no soloing them:P)
		if( pGroup == NULL && (map->israid() || inf->type == INSTANCE_MULTIMODE))
			return INSTANCE_ABORT_NOT_IN_RAID_GROUP;

		//and has the required level
		if( plr->getLevel() < 80)
		{
			if(!map->israid())
			{
				//otherwise we still need to be lvl 70/80 for heroic.
				if( plr->iInstanceType && plr->getLevel() < uint32(inf->HasFlag(WMI_INSTANCE_XPACK_02) ? 80 : 70))
					return INSTANCE_ABORT_HEROIC_MODE_NOT_AVAILABLE;
			}
			else
				//otherwise we still need to be lvl 70/80 for heroic.
				if( plr->iRaidType > 1 && plr->getLevel() < uint32(inf->HasFlag(WMI_INSTANCE_XPACK_02) ? 80 : 70))
					return INSTANCE_ABORT_HEROIC_MODE_NOT_AVAILABLE;

			//and we might need a key too.
			bool reqkey = (inf->heroic_key[0] || inf->heroic_key[1])? true : false;
			bool haskey = (plr->GetItemInterface()->GetItemCount(inf->heroic_key[0], false) || plr->GetItemInterface()->GetItemCount(inf->heroic_key[1], false))? true : false;
			if(reqkey && !haskey)
				return INSTANCE_ABORT_HEROIC_MODE_NOT_AVAILABLE;
		}
	}

	// if we are here, it means:
	// 1) we're a non-raid instance
	// 2) we're a raid instance, and the person is in a group.
	// so, first we have to check if they have an instance on this map already, if so, allow them to teleport to that.
	// next we check if there is a saved instance belonging to him.
	// otherwise, we can create them a new one.

	m_mapLock.Acquire();

	//find all instances for our map
	instancemap = m_instances[mapid];
	if(instancemap)
	{
		InstanceMap::iterator itr;
		// do we have a specific instance id we should enter (saved or active).
		// don't bother looking for saved instances, if we had one we found it in areatrigger.cpp
		if(instanceid != 0)
		{
			itr = instancemap->find(instanceid);
			if(itr != instancemap->end())
			{
				in = itr->second;
				//we have an instance,but can we enter it?
				uint8 owns = PlayerOwnsInstance( in, plr );
				if( owns >= OWNER_CHECK_OK )
				{
					// If the map is active and has players
					if(in->m_mapMgr && in->m_mapMgr->HasPlayers() && !plr->triggerpass_cheat)
					{
						//check if combat is in progress
						if( in->m_mapMgr->IsCombatInProgress())
						{
							m_mapLock.Release();
							return INSTANCE_ABORT_ENCOUNTER;
						}

						// check if we are full
						if( in->m_mapMgr->GetPlayerCount() >= inf->playerlimit )
						{
							m_mapLock.Release();
							return INSTANCE_ABORT_FULL;
						}
					}

					uint32 plrdiff = map->israid() ? plr->iRaidType : plr->iInstanceType;
					if(in->m_difficulty == plrdiff)
					{
						//wakeup call for saved instances
						if(!in->m_mapMgr)
							in->m_mapMgr = _CreateInstance(in);

						if(owns == OWNER_CHECK_SAVED_OK && !in->m_mapMgr->HasPlayers())
						{
							if(plr->GetGroup())
								in->m_creatorGroup = plr->GetGroupID();
						}

						m_mapLock.Release();
						return INSTANCE_OK;
					}
					else
					{
						m_mapLock.Release();
						return INSTANCE_ABORT_TOO_MANY;
					}
				}
				else
					DEBUG_LOG("InstanceMgr","Check failed %s, return code %u",plr->GetName(), owns);
			}
			m_mapLock.Release();
			return INSTANCE_ABORT_NOT_FOUND;
		}
		else
		{
			// search all active instances and see if we have one here.
			for(itr = instancemap->begin(); itr != instancemap->end();)
			{
				in = itr->second;
				++itr;
				//we have an instance,but do we own it?
				uint8 owns = PlayerOwnsInstance(in, plr);
				if( owns >= OWNER_CHECK_OK )
				{
					// check the player count and in combat status.
					if(in->m_mapMgr && in->m_mapMgr->HasPlayers() && !plr->triggerpass_cheat)
					{
						if( in->m_mapMgr->IsCombatInProgress())
						{
							m_mapLock.Release();
							return INSTANCE_ABORT_ENCOUNTER;
						}
						// check if we are full
						if( in->m_mapMgr->GetPlayerCount() >= inf->playerlimit )
						{
							m_mapLock.Release();
							return INSTANCE_ABORT_FULL;
						}
					}

					uint32 plrdiff = map->israid() ? plr->iRaidType : plr->iInstanceType;
					if(in->m_difficulty == plrdiff)
					{
						//wakeup call for saved instances
						if(!in->m_mapMgr)
							in->m_mapMgr = _CreateInstance(in);

						if(owns == OWNER_CHECK_SAVED_OK && !in->m_mapMgr->HasPlayers())
						{
							if(plr->GetGroup())
								in->m_creatorGroup = plr->GetGroupID();
						}

						// found our instance, allow him in.
						m_mapLock.Release();
						return INSTANCE_OK;
					}
				}
				else
					DEBUG_LOG("InstanceMgr","Check failed %s, return code %u",plr->GetName(), owns);
			}
		}
	}
	else
	{
		if(instanceid != 0)
		{
			// wtf, how can we have an instance_id for a mapid which doesn't even exist?
			m_mapLock.Release();
			return INSTANCE_ABORT_NOT_FOUND;
		}
		// this mapid hasn't been added yet, so we gotta create the hashmap now.
		m_instances[mapid] = new InstanceMap;
		instancemap = m_instances[mapid];
	}

	// if we're here, it means we need to create a new instance.
	bool raid = map->israid();
	in = new Instance;
	in->m_creation = UNIXTIME;
	in->m_expiration = (raid ? UNIXTIME + inf->cooldown : 0);		// expire time 0 is 10 minutes after last player leaves
	in->m_creatorGuid = plr->GetLowGUID();
	in->m_creatorGroup = (pGroup ? pGroup->GetID() : 0);
	in->m_difficulty = (raid ? plr->iRaidType : plr->iInstanceType);
	in->m_instanceId = GenerateInstanceID();
	in->m_mapId = mapid;
	in->m_mapMgr = NULLMAPMGR;		// always start off without a map manager, it is created in _CreateInstance(in)

	//crash fix; GM's without group will start up raid instances as if they where nonraids
	//this to avoid exipring check, this is mainly for developers purpose; GM's should NOT invite any players here!
	if( plr->triggerpass_cheat && !plr->GetGroup() && raid)
	{
		const char * message = "Started this instance for development purposes only, do not invite players!!";
		sEventMgr.AddEvent( plr, &Player::_Warn, message, EVENT_UNIT_SENDMESSAGE, 5000, 1, 0);
	}

	in->m_mapInfo = inf;
	in->m_dbcMap = map;
	in->m_isBattleground = false;
	plr->SetInstanceID(in->m_instanceId);
	DEBUG_LOG("InstanceMgr", "Prepared new %s %u for player %u and group %u on map %u with difficulty %u. (%u)", raid ? "Raid" : "Instance" ,in->m_instanceId, in->m_creatorGuid, in->m_creatorGroup, in->m_mapId, in->m_difficulty, in->m_instanceId);

	// apply it in the instance map
	instancemap->insert( InstanceMap::value_type( in->m_instanceId, in ) );

	// create the actual instance (if we don't GetInstance() won't be able to access it).
	in->m_mapMgr = _CreateInstance(in);

	// instance created ok, i guess? return the ok for him to transport.
	m_mapLock.Release();
	return INSTANCE_OK;
}
Example #7
0
MapMgrPointer InstanceMgr::GetInstance(ObjectPointer obj)
{
	PlayerPointer plr;
	Instance * in;
	InstanceMap::iterator itr;
	InstanceMap * instancemap;
	MapInfo * inf = WorldMapInfoStorage.LookupEntry(obj->GetMapId());

	// we can *never* teleport to maps without a mapinfo.
	if( inf == NULL || obj->GetMapId() >= NUM_MAPS )
		return NULLMAPMGR;

	if( obj->IsPlayer() )
	{
		// players can join instances based on their groups/solo status.
		plr = TO_PLAYER( obj );

		// single-instance maps never go into the instance set.
		if( inf->type == INSTANCE_NULL )
			return m_singleMaps[obj->GetMapId()];

		m_mapLock.Acquire();
		instancemap = m_instances[obj->GetMapId()];
		if(instancemap != NULL)
		{
			// check our instance_id, which we saved before in Player::_Relocate
			uint32 plr_instanceID = obj->GetInstanceID();
			itr = instancemap->find(plr_instanceID);
			if(itr != instancemap->end())
			{
				in = itr->second;
				if(in && in->m_mapMgr)
				{
					m_mapLock.Release();
					return in->m_mapMgr;
				}
			}

			
			// iterate over our instances, and see if any of them are owned/joinable by him.
			for(itr = instancemap->begin(); itr != instancemap->end();)
			{
				in = itr->second;
				++itr;

				// Is this our instance?
				uint8 poinst = PlayerOwnsInstance(in, plr);
				if(poinst >= OWNER_CHECK_OK )
				{
					//Has it been created yet?
					if(in->m_mapMgr == NULL)
					{
						// create the actual instance.
						in->m_mapMgr = _CreateInstance(in);
						m_mapLock.Release();
						// first one to enter, set the group instance ID
						if( plr->GetGroup() && !plr->GetSession()->HasGMPermissions() )
							plr->GetGroup()->SetGroupInstanceID(in->m_instanceId);
						return in->m_mapMgr;
					}
					else // instance has found and verfied; us it.
					{
						if( poinst != OWNER_CHECK_GM_INSIDE && in->m_mapMgr->HasPlayers() && plr->GetGroup() && plr->GetGroup()->GetGroupInstanceID() != in->m_instanceId )
						{
							Log.Warning("InstanceMgr","Reset GroupInstanceID for existing instance %u [%s] , old_ID = %u, new_ID = %u", in->m_mapId, in->m_mapInfo->name, plr->GetGroup()->GetGroupInstanceID(), in->m_instanceId );
							plr->GetGroup()->SetGroupInstanceID(in->m_instanceId);
						}
						else if(in->m_mapMgr->HasPlayers() && plr->GetGroup() && plr->GetGroup()->GetGroupInstanceID() != in->m_instanceId)
						{
							Log.Warning("InstanceMgr","Forced GroupInstanceID for instance %u [%s] started by GM, old_ID = %u, new_ID = %u", in->m_mapId, in->m_mapInfo->name, plr->GetGroup()->GetGroupInstanceID(), in->m_instanceId );
							plr->GetGroup()->SetGroupInstanceID(in->m_instanceId);
						}
						m_mapLock.Release();
						return in->m_mapMgr;
					}
				}
				else
					DEBUG_LOG("InstanceMgr","Check failed %s",plr->GetName());
			}
		}

		// if we're here, it means there are no instances on that map, or none of the instances on that map are joinable
		// by this player.
		m_mapLock.Release();
		return NULLMAPMGR;
	}
	else
	{
		// units are *always* limited to their set instance ids.
		if(inf->type == INSTANCE_NULL)
			return m_singleMaps[obj->GetMapId()];

		m_mapLock.Acquire();
		instancemap = m_instances[obj->GetMapId()];
		if(instancemap)
		{
			itr = instancemap->find(obj->GetInstanceID());
			if(itr != instancemap->end())
			{
				// we never create instances just for units.
				m_mapLock.Release();
				return itr->second->m_mapMgr;
			}
		}

		// instance is non-existant (shouldn't really happen for units...)
		m_mapLock.Release();
		return NULLMAPMGR;
	}
}
Example #8
0
uint32 InstanceMgr::PreTeleport(uint32 mapid, PlayerPointer plr, uint32 instanceid)
{
	// preteleport is where all the magic happens :P instance creation, etc.
	MapInfo * inf = WorldMapInfoStorage.LookupEntry(mapid);
	Group * pGroup = plr->GetGroup() ;
	InstanceMap * instancemap;
	Instance * in;

	if(inf == NULL || mapid>=NUM_MAPS)
		return INSTANCE_ABORT_NOT_FOUND;

	// main continent check.
	if(inf->type == INSTANCE_NULL)
	{
		// this will be useful when clustering comes into play.
		// we can check if the destination world server is online or not and then cancel them before they load.
		return (m_singleMaps[mapid] != NULL) ? INSTANCE_OK : INSTANCE_ABORT_NOT_FOUND;
	}

	// shouldn't happen
	if(inf->type==INSTANCE_PVP)
		return INSTANCE_ABORT_NOT_FOUND;

	if( !plr->triggerpass_cheat )
	{
		// players without groups cannot enter raid instances (no soloing them:P)
		if( pGroup == NULL && (inf->type == INSTANCE_RAID || inf->type == INSTANCE_MULTIMODE))
			return INSTANCE_ABORT_NOT_IN_RAID_GROUP;

		// check that heroic mode is available if the player has requested it.
		if(plr->iInstanceType && inf->type != INSTANCE_MULTIMODE)
			return INSTANCE_ABORT_HEROIC_MODE_NOT_AVAILABLE;
	}

	// if we are here, it means:
	// 1) we're a non-raid instance
	// 2) we're a raid instance, and the person is in a group.
	// so, first we have to check if they have an instance on this map already, if so, allow them to teleport to that.
	// otherwise, we can create them a new one.
	m_mapLock.Acquire();
	instancemap = m_instances[mapid];

	if(instancemap)
	{
		InstanceMap::iterator itr;
		if(instanceid != 0)
		{
			//try to find our instance in ones active now.
			itr = instancemap->find(instanceid);
			if(itr != instancemap->end()) 
			{
				Instance *inn = itr->second;
				if( PlayerOwnsInstance( inn, plr ) >= OWNER_CHECK_OK )
				{
					m_mapLock.Release();
					return INSTANCE_OK;
				}
			}
			//There are no active maps, re-check if this concerns a  saved instance.
			Instance * saved_in = sInstanceMgr.GetSavedInstance( mapid, plr->GetLowGUID() );
			if( saved_in && saved_in->m_instanceId == instanceid )
			{
				if ( PlayerOwnsInstance( saved_in, plr ) >= OWNER_CHECK_OK )
				{
					m_mapLock.Release();
					return INSTANCE_OK;
				}
			}
			m_mapLock.Release();
			return INSTANCE_ABORT_NOT_FOUND;
		}
		else
		{
			// search all active instances and see if we have one here.
			for(itr = instancemap->begin(); itr != instancemap->end();)
			{
				in = itr->second;
				++itr;
				if(PlayerOwnsInstance(in, plr) >= OWNER_CHECK_OK )
				{
					m_mapLock.Release();

					// check the player count and in combat status.
					if(in->m_mapMgr && in->m_mapMgr->HasPlayers() && !plr->triggerpass_cheat)
					{
						if( in->m_mapMgr->IsCombatInProgress())
							return INSTANCE_ABORT_ENCOUNTER;

						// check if we are full
						if( in->m_mapMgr->GetPlayerCount() >= inf->playerlimit )
							return INSTANCE_ABORT_FULL;

					}

					// found our instance, allow him in.
					return INSTANCE_OK;
				}
				else
					DEBUG_LOG("InstanceMgr","Check failed %s",plr->GetName());
			}
		}
	}
	else
	{
		if(instanceid != 0)
		{
			return INSTANCE_ABORT_NOT_FOUND;

		}
		// gotta create the hashmap.
		m_instances[mapid] = new InstanceMap;
		instancemap = m_instances[mapid];
	}

	// if we're here, it means we need to create a new instance.
	in = new Instance;
	in->m_creation = UNIXTIME;
	in->m_expiration = (inf->type == INSTANCE_NONRAID) ? 0 : UNIXTIME + inf->cooldown;		// expire time 0 is 10 minutes after last player leaves
	in->m_creatorGuid = pGroup ? 0 : plr->GetLowGUID();		// creator guid is 0 if its owned by a group.
	in->m_creatorGroup = pGroup ? pGroup->GetID() : 0;
	in->m_difficulty = plr->iInstanceType;
	in->m_instanceId = GenerateInstanceID();
	in->m_mapId = mapid;
	in->m_mapMgr = NULLMAPMGR;		// always start off without a map manager, it is created in GetInstance()

	//crash fix; GM's without group will start up raid instances as if they where nonraids
	//this to avoid exipring check, this is mainly for developers purpose; GM's should NOT invite any players here!
	if( plr->triggerpass_cheat && !plr->GetGroup() && inf->type == INSTANCE_RAID)
	{
		inf->type = INSTANCE_NONRAID;
		sGMLog.writefromsession(plr->GetSession(), "Started a raid instance %d [%s] as non_raid instance.", mapid, inf->name);
		DEBUG_LOG("InstanceMgr","Started a raid instance %d [%s] as non_raid instance.", mapid, inf->name);
	}

	in->m_mapInfo = inf;
	in->m_isBattleground=false;
	plr->SetInstanceID(in->m_instanceId);
	if( plr->GetGroup() && !plr->GetSession()->HasGMPermissions())//GM should not set the instanceID
		pGroup->SetGroupInstanceID(in->m_instanceId);
	DEBUG_LOG("InstanceMgr", "Prepared new instance %u for player %u and group %u on map %u. (%u)",in->m_instanceId, in->m_creatorGuid, in->m_creatorGroup, in->m_mapId, in->m_instanceId);


	// apply it in the instance map
	instancemap->insert( InstanceMap::value_type( in->m_instanceId, in ) );

	// create the actual instance (if we don't GetInstance() won't be able to access it).
	in->m_mapMgr = _CreateInstance(in);

	// instance created ok, i guess? return the ok for him to transport.
	m_mapLock.Release();
	return INSTANCE_OK;
}
Example #9
0
STDAPI SHCoCreateInstance(LPCTSTR pszCLSID, const CLSID * pclsid,
                LPUNKNOWN pUnkOuter, REFIID riid, LPVOID FAR* ppv)
{
    HRESULT hres = ResultFromScode(REGDB_E_CLASSNOTREG);
    CLSID clsidT;
    TCHAR szClass[GUIDSTR_MAX+ARRAYSIZE(c_szInProcServer)];

    if (pclsid)
    {
        if (!pszCLSID)
        {
            StringFromGUID2A(pclsid, szClass, ARRAYSIZE(szClass));
        }
    }
    else
    {
        if (pszCLSID)
        {
            lstrcpy(szClass,pszCLSID);
            if (SUCCEEDED(SHCLSIDFromString(pszCLSID, &clsidT)))
                pclsid=&clsidT;
        }
    }


    if (pclsid)
    {
        LONG err;
        HKEY hkeyDll;
        IClassFactory *pCF;

        Assert(hres == ResultFromScode(REGDB_E_CLASSNOTREG));

        lstrcat(szClass,c_szInProcServer);  // Add "\InProcServer32"

        hres = _FindRegisteredClass(pclsid, &pCF);
        if (SUCCEEDED(hres))
        {
            hres = pCF->lpVtbl->CreateInstance(pCF, pUnkOuter, riid, ppv);
            pCF->lpVtbl->Release(pCF);
        }
        else
        {
            if (g_hkcrCLSID && RegOpenKey(g_hkcrCLSID, szClass, &hkeyDll) == ERROR_SUCCESS)
            {
                TCHAR szDllName[MAX_PATH];
                LONG cbValue = SIZEOF(szDllName);

                //            1         2         3
                //  012345678901234567890123456789012345678  = nul is at 38!
                // "{12345678-1234-1234-1234-123456789012}"
                //
                szClass[38] = TEXT('\0');   // Get rid of "\InProcServer32"

                err = RegQueryValue(hkeyDll, NULL, szDllName, &cbValue);

#ifdef WINNT
                //
                // On NT, we must check to ensure that this CLSID exists in
                // the list of approved CLSIDs that can be used in-process.
                // If not, we fail the creation with ERROR_ACCESS_DENIED.
                // We explicitly allow anything serviced by this DLL
                //

                if (err == ERROR_SUCCESS && NULL != g_hklmApprovedExt)
                {
                    TCHAR szBuf[MAX_PATH];

                    //
                    // Check to see if we are using this DLL
                    //
                    // BUGBUG Assumes no parameters in InProcServer32.  We
                    // should remove this assumption once we lose shellalt,
                    // after which we can just lstrcpyn(,,<length of dll name>);

                    LPCTSTR pszDllName = PathFindFileName(szDllName);

                    if (lstrcmp(pszDllName, TEXT("shell32.dll")) &&
                        lstrcmp(pszDllName, TEXT("shellalt.dll")))
                    {
                        DWORD dwType;
                        TCHAR szValue[MAX_PATH];
                        DWORD cbSize = SIZEOF(szValue);

                        if (ERROR_SUCCESS != RegQueryValueEx(g_hklmApprovedExt,
                                                             szClass,
                                                             0,
                                                             &dwType,
                                                             (LPBYTE) szValue,
                                                             &cbSize))
                        {
                            hres = HRESULT_FROM_WIN32(ERROR_ACCESS_DENIED);
                            return hres;
                        }
                    }
                }
#endif

                if (err == ERROR_SUCCESS)
                {
                    TCHAR szThreadingModel[MAX_PATH];
                    BOOL fMultiThreadAware = FALSE;
                    DWORD dwRegType;
                    DWORD cbRead = SIZEOF(szThreadingModel);

                    err = RegQueryValueEx(hkeyDll, c_szThreadingModel, NULL,
                            &dwRegType, (LPBYTE)szThreadingModel, &cbRead);
                    if (err == ERROR_SUCCESS && dwRegType == REG_SZ)
                    {
                        if (lstrcmpi(szThreadingModel, c_szApartment)==0
                            || lstrcmpi(szThreadingModel, c_szBoth)==0)
                        {
                            fMultiThreadAware = TRUE;
                        }
                    }

// #define HACK_APARTMENT_ONLY_ASSERT
#ifdef HACK_APARTMENT_ONLY_ASSERT
                    if (!fMultiThreadAware)
                    {
                        _asm {
                            int 3;
                        }
                    }
                    Assert(fMultiThreadAware);
                    hres = _CreateInstance(pclsid, szDllName, pUnkOuter, riid, ppv);
#else
                    if (fMultiThreadAware)
                    {
                        hres = _CreateInstance(pclsid, szDllName, pUnkOuter, riid, ppv);
                    }
                    else
                    {
                        Assert(hres == ResultFromScode(REGDB_E_CLASSNOTREG));
                        DebugMsg(DM_ERROR, TEXT("sh TR - SHCoCreateInstance !!! InProcServer32 (%s) does not support multi-threading"), szDllName);
                        Assert(0);
                    }
#endif

                }

                RegCloseKey(hkeyDll);
            }