예제 #1
0
bool CNNM2ECC::addNewGroup(string svname, svutil::word & putid, string parentid)
{
	WORDLIST subglist;

	//获取所有子孙 id 
	if(parentid.find(".")==std::string::npos)
	{
		OBJECT objse= Cache_GetSVSE(parentid);
		if( objse==INVALID_VALUE )
			return false;
		SVSE *se= reinterpret_cast<SVSE *>(objse);
		if(se==NULL)
			return false;
		subglist= se->GetSubGroups();
	}
	else
	{
		OBJECT objgroup= Cache_GetGroup( parentid );
		if(objgroup==INVALID_VALUE)
			return false;
		Group* pNnmGroup = reinterpret_cast<Group *>(objgroup);
		if(pNnmGroup==NULL)
			return false;
		subglist= pNnmGroup->GetSubGroups();
	}

	//遍历子孙
	for(WORDLIST::iterator it1=subglist.begin();it1!=subglist.end();it1++)
	{
		OBJECT objgroup2= Cache_GetGroup( (*it1).getword() );
		if(objgroup2==INVALID_VALUE)
			continue;
		Group *pGroup = reinterpret_cast<Group *>(objgroup2);
		if(pGroup!=NULL)
		{
			std::string groupname = svname.c_str();
			if(groupname.compare((pGroup->GetProperty())["sv_name"])==0)
			{
				putid = pGroup->GetID();
				return true;
			}
		}
	}

	//如果没有发现需要的子孙,则新建
	OBJECT newobj= CreateGroup();
	if(newobj==INVALID_VALUE)
		return false;
	Group* pg= reinterpret_cast<Group *>(newobj);
	if(pg==NULL)
		return false;

	(pg->GetProperty())["sv_name"]= svname.c_str();
	putid = AddNewGroup(newobj,parentid);
	bool ret= SubmitGroup(newobj);
	CloseGroup( newobj );
	return ret;
}
예제 #2
0
////////////////////////////////////////////////////////////////
///This function handles CMSG_GROUP_ACCEPT:
////////////////////////////////////////////////////////////////
void WorldSession::HandleGroupAcceptOpcode(WorldPacket & recv_data)
{
	CHECK_INWORLD_RETURN;

	// we are in group already
	if(_player->GetGroup() != NULL)
		return;

	Player* player = objmgr.GetPlayer(_player->GetInviter());
	if(!player)
		return;

	player->SetInviter(0);
	_player->SetInviter(0);

	Group* grp = player->GetGroup();
	if(grp != NULL)
	{
		grp->AddMember(_player->m_playerInfo);
		_player->iInstanceType = grp->m_difficulty;
		_player->SendDungeonDifficulty();

		//sInstanceSavingManager.ResetSavedInstancesForPlayer(_player);
		return;
	}

	// If we're this far, it means we have no existing group, and have to make one.
	grp = new Group(true);
	grp->m_difficulty = static_cast<uint8>(player->iInstanceType);
	grp->AddMember(player->m_playerInfo);		// add the inviter first, therefore he is the leader
	grp->AddMember(_player->m_playerInfo);	// add us.
	_player->iInstanceType = grp->m_difficulty;
	_player->SendDungeonDifficulty();

	Instance* instance = sInstanceMgr.GetInstanceByIds(player->GetMapId(), player->GetInstanceID());
	if(instance != NULL && instance->m_creatorGuid == player->GetLowGUID())
	{
		grp->m_instanceIds[instance->m_mapId][instance->m_difficulty] = instance->m_instanceId;
		instance->m_creatorGroup = grp->GetID();
		instance->m_creatorGuid = 0;
		instance->SaveToDB();
	}

	//sInstanceSavingManager.ResetSavedInstancesForPlayer(_player);

	// Currentgroup and all that shit are set by addmember.
}
예제 #3
0
bool ChatHandler::HandleResetInstanceCommand(const char* args, WorldSession* m_session)
{

    uint32 instanceId;
    int argc = 1;
    char* playername = NULL;
    char* guidString = (char*)args;

    // Parse arguments
    char* space = (char*)strchr(args, ' ');
    if (space)
    {
        *space = '\0';
        playername = space + 1;
        argc = 2;
    }

    instanceId = atoi(guidString);
    if (!instanceId)
    {
        RedSystemMessage(m_session, "You must specify an instance id.");
        return true;
    }


    Player* plr;

    if (argc == 1)
        plr = getSelectedChar(m_session, true);
    else
        plr = objmgr.GetPlayer((const char*)playername, false);;

    if (!plr)
    {
        RedSystemMessage(m_session, "Player not found");
        return true;
    }

    Instance* instance = sInstanceMgr.GetInstanceByIds(NUM_MAPS, instanceId);
    if (instance == NULL)
    {
        RedSystemMessage(m_session, "There's no instance with id %u.", instanceId);
        return true;
    }

    if (IS_PERSISTENT_INSTANCE(instance))
    {
        if (m_session->CanUseCommand('z'))
        {
            bool foundSomething = false;
            plr->getPlayerInfo()->savedInstanceIdsLock.Acquire();
            for (uint32 difficulty = 0; difficulty < NUM_INSTANCE_MODES; difficulty++)
            {
                PlayerInstanceMap::iterator itr = plr->getPlayerInfo()->savedInstanceIds[difficulty].find(instance->m_mapId);
                if (itr == plr->getPlayerInfo()->savedInstanceIds[difficulty].end() || (*itr).second != instance->m_instanceId)
                    continue;
                plr->SetPersistentInstanceId(instance->m_mapId, difficulty, 0);
                SystemMessage(m_session, "Instance with id %u (%s) is persistent and will only be revoked from player.", instanceId, GetDifficultyString(static_cast<uint8>(difficulty)));
                foundSomething = true;
            }
            plr->getPlayerInfo()->savedInstanceIdsLock.Release();
            if (!foundSomething)
                RedSystemMessage(m_session, "Player is not assigned to persistent instance with id %u.", instanceId);
            return true;
        }
        else
        {
            RedSystemMessage(m_session, "Instance with id %u is persistent and can only be removed from player by admins.", instanceId);
            return true;
        }
    }

    if (instance->m_mapMgr && instance->m_mapMgr->HasPlayers())
    {
        RedSystemMessage(m_session, "Failed to reset non-persistent instance with id %u, due to player still inside.", instanceId);
        return true;
    }

    if (instance->m_creatorGroup)
    {
        Group* group = plr->GetGroup();
        if (group == NULL || instance->m_creatorGroup != group->GetID())
        {
            RedSystemMessage(m_session, "Player %s is not a member of the group assigned to the non-persistent instance with id %u.", plr->GetName(), instanceId);
            return true;
        }
    }
    else if (instance->m_creatorGuid == 0 || instance->m_creatorGuid != plr->GetLowGUID())
    {
        RedSystemMessage(m_session, "Player %s is not assigned to instance with id %u.", plr->GetName(), instanceId);
        return true;
    }

    // tell player the instance was reset
    WorldPacket data(SMSG_INSTANCE_RESET, 4);
    data << instance->m_mapId;
    plr->GetSession()->SendPacket(&data);

    // shut down instance
    sInstanceMgr.DeleteBattlegroundInstance(instance->m_mapId, instance->m_instanceId);
    //    RedSystemMessage(m_session, "Resetting single non-persistent instances is not available yet.");
    sGMLog.writefromsession(m_session, "used reset instance command on %s, instance %u,", plr->GetName(), instanceId);
    return true;
}
예제 #4
0
uint32 InstanceMgr::PreTeleport(uint32 mapid, Player* plr, uint32 instanceid)
{
	// preteleport is where all the magic happens :P instance creation, etc.
	MapInfo* inf = WorldMapInfoStorage.LookupEntry(mapid);
	Group* pGroup;
	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_BATTLEGROUND)
		return INSTANCE_ABORT_NOT_FOUND;

	pGroup = plr->GetGroup();

	// players without groups cannot enter raids and heroic instances

	if(pGroup == NULL &&
	        inf->type == INSTANCE_RAID &&
	        !plr->TriggerpassCheat)
		return INSTANCE_ABORT_NOT_IN_RAID_GROUP;

	if(pGroup == NULL &&
	        (inf->type == INSTANCE_NONRAID && plr->iInstanceType == MODE_HEROIC) &&
	        !plr->TriggerpassCheat)
		return INSTANCE_ABORT_NOT_IN_RAID_GROUP;


	// players without raid groups cannot enter raid instances
	if(pGroup != NULL && pGroup->GetGroupType() != GROUP_TYPE_RAID && inf->type == INSTANCE_RAID && !plr->TriggerpassCheat)
		return INSTANCE_ABORT_NOT_IN_RAID_GROUP;

	// We deny transfer if we requested a heroic instance of a map that has no heroic mode
	// We are trying to enter into a non-multi instance with a heroic group, downscaling
	if(inf->type == INSTANCE_NONRAID && plr->GetDungeonDifficulty() == MODE_HEROIC)
	{
		plr->SetDungeonDifficulty(MODE_NORMAL);
		plr->SendDungeonDifficulty();

		Group* grp = plr->GetGroup();
		if(grp != NULL)
			grp->SetDungeonDifficulty(MODE_NORMAL);
	}

	// if it's not a normal / 10men normal then check if we even have this mode
	if(inf->type == INSTANCE_RAID && plr->GetRaidDifficulty() != MODE_NORMAL_10MEN)
	{
		uint32 newtype = 0;

		if(!inf->HasDifficulty(plr->GetRaidDifficulty()))
		{
			// no it doesn't so we will downscale it

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// This part is totally speculative, if you know how this is done actually then do change it
//
			switch(plr->GetRaidDifficulty())
			{
				case MODE_NORMAL_25MEN:
				case MODE_HEROIC_10MEN:
					{
						newtype = MODE_NORMAL_10MEN;
						break;
					}

				case MODE_HEROIC_25MEN:
					{
						newtype = MODE_NORMAL_25MEN;
						break;
					}
			}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

			// check if we have this mode
			if(!inf->HasDifficulty(newtype))
			{

				//appearantly we don't so we set to 10men normal, which is the default for old raids too
				//regardless of their playerlimit
				newtype = MODE_NORMAL_10MEN;
			}

			// Setting the new mode on us and our group
			if(plr->GetRaidDifficulty() != newtype)
			{

				plr->SetRaidDifficulty(newtype);
				plr->SendRaidDifficulty();

				Group* grp = plr->GetGroup();
				if(grp != NULL)
					grp->SetRaidDifficulty(newtype);
			}
		}
	}

	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	// If we are here, it means:
	// 1.) We're a simple non-raid and non-heroic dungeon
	// 2.) We're a multi-dungeon set to heroic and we are in a group
	// 3.) We're a raid, and we are in a raid group
	// 4.) We're a raid, we are in a raid group, and we have the right mode set
	//
	// 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 will try to create them a new one.
	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

	m_mapLock.Acquire();
	instancemap = m_instances[mapid];

	// If there are no instances of this map yet, we need to create the map
	if(instancemap == NULL)
	{
		if(instanceid != 0)
		{
			m_mapLock.Release();
			return INSTANCE_ABORT_NOT_FOUND;
		}

		m_instances[mapid] = new InstanceMap;
		instancemap = m_instances[mapid];
	}
	else
	{
		InstanceMap::iterator itr;

		// this is the case when we enter an already existing instance ( with summons for example )
		if(instanceid != 0)
		{
			itr = instancemap->find(instanceid);
			if(itr != instancemap->end())
			{
				in = itr->second;

				if(!CHECK_INSTANCE_GROUP(in, pGroup))
				{
					// Another group is already playing in this instance of the dungeon...
					m_mapLock.Release();
					sChatHandler.SystemMessageToPlr(plr, "Another group is already inside this instance of the dungeon.");
					return INSTANCE_ABORT_NOT_IN_RAID_GROUP;
				}

				// Try to add instance ID to player
				plr->SetPersistentInstanceId(in);

				// Set current group
				if(pGroup)
					in->m_creatorGroup = pGroup->GetID();

				m_mapLock.Release();
				return INSTANCE_OK;
			}
			else
			{
				m_mapLock.Release();
				return INSTANCE_ABORT_NOT_FOUND;
			}
		}
		else  // this is the case when we enter the normal way (e.g. we enter thru the portal )
		{
			in = NULL;
			if(pGroup != NULL) // we are in a group
			{

				uint32 grpdiff;

				// We want to use the raid difficulty for raids, and dungeon difficulty for dungeons
				if(inf->type == INSTANCE_RAID)
					grpdiff = pGroup->m_raiddifficulty;
				else
					grpdiff = pGroup->m_difficulty;

				if((inf->type == INSTANCE_MULTIMODE && grpdiff == MODE_HEROIC) || inf->type == INSTANCE_RAID)
				{
					// This is the case when we don't have this map on this difficulty saved yet for the player entering
					if(plr->GetPersistentInstanceId(mapid, grpdiff) == 0)
					{
						// The group has this instance saved already so we will use it
						if(pGroup->m_instanceIds[mapid][ grpdiff ] != 0)
						{
							in = sInstanceMgr.GetInstanceByIds(mapid, pGroup->m_instanceIds[mapid][ grpdiff ]);
						}
						else if(sWorld.instance_TakeGroupLeaderID)
						{
							PlayerInfo* pLeaderInfo = pGroup->GetLeader();
							if(pLeaderInfo)
							{
								pLeaderInfo->savedInstanceIdsLock.Acquire();
								PlayerInstanceMap::iterator itrLeader = pLeaderInfo->savedInstanceIds[ grpdiff ].find(mapid);
								if(itrLeader != pLeaderInfo->savedInstanceIds[ grpdiff ].end())
								{
									in = sInstanceMgr.GetInstanceByIds(mapid, (*itrLeader).second);
								}
								pLeaderInfo->savedInstanceIdsLock.Release();
							}
						}
					}

					// If we have it saved to the player then use that
					if(in == NULL && plr->GetPersistentInstanceId(mapid, grpdiff) != 0)
					{
						in = sInstanceMgr.GetInstanceByIds(mapid, plr->GetPersistentInstanceId(mapid, grpdiff));
					}
				}
				else
				{
					if(pGroup->m_instanceIds[mapid][ grpdiff ] != 0)
					{
						in = sInstanceMgr.GetInstanceByIds(mapid, pGroup->m_instanceIds[mapid][ grpdiff ]);
					}
				}
			}

			if(in == NULL)
			{
				// We are not in a group, so we will look for an instance that we own and has the right difficulty

				uint32 diff;

				if(inf->type == INSTANCE_RAID)
					diff = plr->GetRaidDifficulty();
				else
					diff = plr->GetDungeonDifficulty();

				for(itr = instancemap->begin(); itr != instancemap->end();)
				{
					in = itr->second;
					++itr;

					if(in->m_difficulty == diff && PlayerOwnsInstance(in, plr))
						break;

					in = NULL;
				}
			}

			// We've found an instance!
			if(in != NULL)
			{
				m_mapLock.Release();

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

					if(in->m_mapMgr->GetPlayerCount() >= inf->playerlimit)
						return INSTANCE_ABORT_FULL;
				}

				if(!CHECK_INSTANCE_GROUP(in, pGroup))
				{
					// Another group is already playing in this instance of the dungeon...
					sChatHandler.SystemMessageToPlr(plr, "Another group is already inside this instance of the dungeon.");
					return INSTANCE_ABORT_NOT_IN_RAID_GROUP;
				}

				// Try to add instance ID to player
				plr->SetPersistentInstanceId(in);

				// Set current group
				if(pGroup)
					in->m_creatorGroup = pGroup->GetID();

				plr->SetInstanceID(in->m_instanceId);

				// found our instance, allow him in.
				return INSTANCE_OK;
			}
		}
	}

	// if we're here, it means we need to create a new instance.
	in = new Instance;
	in->m_creation = UNIXTIME;

	switch(inf->type)
	{
		case INSTANCE_NONRAID:
		case INSTANCE_MULTIMODE:
			in->m_difficulty = plr->GetDungeonDifficulty();
			break;

		case INSTANCE_RAID:
			in->m_difficulty = plr->GetRaidDifficulty();
			break;
	}

	in->m_instanceId = GenerateInstanceID();
	in->m_mapId = mapid;
	in->m_mapInfo = inf;
	in->m_mapMgr = NULL;		// always start off without a map manager, it is created in GetInstance()
	in->m_isBattleground = false;
	in->m_persistent = IS_PERSISTENT_INSTANCE(in) && objmgr.m_InstanceBossInfoMap[mapid] == NULL;
	in->m_creatorGuid = pGroup ? 0 : plr->GetLowGUID();		// creator guid is 0 if its owned by a group.
	in->m_creatorGroup = pGroup ? pGroup->GetID() : 0;

	if(sWorld.instance_SlidingExpiration)
	{
		if(inf->type == INSTANCE_MULTIMODE && in->m_difficulty == MODE_HEROIC)
			in->m_expiration = UNIXTIME + TIME_DAY;
		else
			in->m_expiration = (inf->type == INSTANCE_NONRAID || (inf->type == INSTANCE_MULTIMODE && in->m_difficulty == MODE_NORMAL)) ? 0 : UNIXTIME + inf->cooldown;
	}
	else
	{
		if(inf->type == INSTANCE_MULTIMODE && in->m_difficulty >= MODE_HEROIC)
		{
			in->m_expiration = UNIXTIME - (UNIXTIME % TIME_DAY) + ((UNIXTIME % TIME_DAY) > (sWorld.instance_DailyHeroicInstanceResetHour * TIME_HOUR) ? 82800 : -3600) + ((sWorld.instance_DailyHeroicInstanceResetHour - sWorld.GMTTimeZone) * TIME_HOUR);
		}
		else if(IS_PERSISTENT_INSTANCE(in))
		{
			if(m_nextInstanceReset[in->m_mapId] == 0)
			{
				m_nextInstanceReset[in->m_mapId] = UNIXTIME - (UNIXTIME % TIME_DAY) - ((sWorld.GMTTimeZone + 1) * TIME_HOUR) + (in->m_mapInfo->cooldown == 0 ? TIME_DAY : in->m_mapInfo->cooldown);
				CharacterDatabase.Execute("DELETE FROM server_settings WHERE setting_id LIKE 'next_instance_reset_%u';", in->m_mapId);
				CharacterDatabase.Execute("INSERT INTO server_settings VALUES ('next_instance_reset_%u', '%u')", in->m_mapId, m_nextInstanceReset[in->m_mapId]);
			}
			if(m_nextInstanceReset[in->m_mapId] + (TIME_MINUTE * 15) < UNIXTIME)
			{
				do
				{
					time_t tmp = m_nextInstanceReset[in->m_mapId];
					if(tmp + (TIME_MINUTE * 15) < UNIXTIME)
						m_nextInstanceReset[in->m_mapId] = tmp + (in->m_mapInfo->cooldown == 0 ? TIME_DAY : in->m_mapInfo->cooldown);
				}
				while(m_nextInstanceReset[in->m_mapId] + (TIME_MINUTE * 15) < UNIXTIME);
				CharacterDatabase.Execute("DELETE FROM server_settings WHERE setting_id LIKE 'next_instance_reset_%u';", in->m_mapId);
				CharacterDatabase.Execute("INSERT INTO server_settings VALUES ('next_instance_reset_%u', '%u')", in->m_mapId, m_nextInstanceReset[in->m_mapId]);
			}
			in->m_expiration = m_nextInstanceReset[in->m_mapId];
		}
		else
		{
			in->m_expiration = (inf->type == INSTANCE_NONRAID || (inf->type == INSTANCE_MULTIMODE && in->m_difficulty == MODE_NORMAL)) ? 0 : UNIXTIME + inf->cooldown;
		}
	}
	plr->SetInstanceID(in->m_instanceId);
	Log.Debug("InstanceMgr", "Creating instance for player %u and group %u on map %u. (%u)", in->m_creatorGuid, in->m_creatorGroup, in->m_mapId, in->m_instanceId);

	// save our new instance to the database.
	in->SaveToDB();

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

	// Try to add instance ID to player
	plr->SetPersistentInstanceId(in);

	// instance created ok, i guess? return the ok for him to transport.
	m_mapLock.Release();

	return INSTANCE_OK;
}
예제 #5
0
void CBattlegroundManager::HandleArenaJoin(WorldSession * m_session, uint32 BattlegroundType, uint8 as_group, uint8 rated_match)
{
	uint32 pguid = m_session->GetPlayer()->GetLowGUID();
	uint32 lgroup = GetLevelGrouping(m_session->GetPlayer()->getLevel());
	if(as_group && m_session->GetPlayer()->GetGroup() == NULL)
		return;

	Group * pGroup = m_session->GetPlayer()->GetGroup();
	if(as_group)
	{
		if(pGroup->GetSubGroupCount() != 1)
		{
			m_session->SystemMessage("Sorry, raid groups joining battlegrounds are currently unsupported.");
			return;
		}
		if(pGroup->GetLeader() != m_session->GetPlayer()->m_playerInfo)
		{
			m_session->SystemMessage("You must be the party leader to add a group to an arena.");
			return;
		}

		GroupMembersSet::iterator itx;
		if(!rated_match)
		{
			/* add all players normally.. bleh ;P */
			pGroup->Lock();
			for(itx = pGroup->GetSubGroup(0)->GetGroupMembersBegin(); itx != pGroup->GetSubGroup(0)->GetGroupMembersEnd(); ++itx)
			{
				if((*itx)->m_loggedInPlayer && !(*itx)->m_loggedInPlayer->m_bgIsQueued && !(*itx)->m_loggedInPlayer->m_bg)
					HandleArenaJoin((*itx)->m_loggedInPlayer->GetSession(), BattlegroundType, 0, 0);
			}
			pGroup->Unlock();
			return;
		}
		else
		{
			/* make sure all players are 70 */
			uint32 maxplayers;
			uint32 arenateamtype;
			switch(BattlegroundType)
			{
			case BATTLEGROUND_ARENA_2V2:
				arenateamtype=0;
				maxplayers=2;
				break;

			case BATTLEGROUND_ARENA_3V3:
				arenateamtype=1;
				maxplayers=3;
				break;

			case BATTLEGROUND_ARENA_5V5:
				arenateamtype=2;
				maxplayers=5;
				break;

			default:
				arenateamtype=0;
				maxplayers=2;
				break;
			}

			uint32 team_id = 0;

			pGroup->Lock();
			for(itx = pGroup->GetSubGroup(0)->GetGroupMembersBegin(); itx != pGroup->GetSubGroup(0)->GetGroupMembersEnd(); ++itx)
			{
				if( maxplayers == 0 )
				{
					m_session->SystemMessage("You have too many players in your party to join this type of arena.");
					pGroup->Unlock();
					return;
				}

				if((*itx)->lastLevel < 70)
				{
					m_session->SystemMessage("Sorry, some of your party members are not level 70.");
					pGroup->Unlock();
					return;
				}

				if((*itx)->m_loggedInPlayer)
				{
					ArenaTeam * t = (*itx)->m_loggedInPlayer->m_arenaTeams[arenateamtype];
					if( t != NULL )
					{
						if ( team_id == 0 )
							team_id = t->m_id;

						if ( team_id != t->m_id )
						{
							m_session->SystemMessage("Sorry, not all your party members are in same arena team.");
							pGroup->Unlock();
							return;
						}
					}
					else
					{
						m_session->SystemMessage("Sorry, not all your party members are in same arena team.");
						pGroup->Unlock();
						return;
					}

					if( (*itx)->m_loggedInPlayer->m_bgIsQueued )
						BattlegroundManager.RemovePlayerFromQueues((*itx)->m_loggedInPlayer);

					/*
					if((*itx)->m_loggedInPlayer->m_bg || (*itx)->m_loggedInPlayer->m_bg || (*itx)->m_loggedInPlayer->m_bgIsQueued)
					{
						m_session->SystemMessage("One or more of your party members are already queued or inside a battleground.");
						pGroup->Unlock();
						return;
					}
					*/

					--maxplayers;
				}
			}
			if( maxplayers > 0 )
			{
				m_session->SystemMessage("Sorry, you have too few valid arena members in your group.");
				pGroup->Unlock();
				return;
			}

			WorldPacket data(SMSG_GROUP_JOINED_BATTLEGROUND, 4);
			data << uint32(6);		// all arenas

			for(itx = pGroup->GetSubGroup(0)->GetGroupMembersBegin(); itx != pGroup->GetSubGroup(0)->GetGroupMembersEnd(); ++itx)
			{
				if((*itx)->m_loggedInPlayer)
				{
					SendBattlefieldStatus((*itx)->m_loggedInPlayer, 1, BattlegroundType, 0 , 0, 0,1);
					(*itx)->m_loggedInPlayer->m_bgIsQueued = true;
					(*itx)->m_loggedInPlayer->m_bgQueueInstanceId = 0;
					(*itx)->m_loggedInPlayer->m_bgQueueType = BattlegroundType;
					(*itx)->m_loggedInPlayer->GetSession()->SendPacket(&data);
					(*itx)->m_loggedInPlayer->m_bgEntryPointX=(*itx)->m_loggedInPlayer->GetPositionX();
					(*itx)->m_loggedInPlayer->m_bgEntryPointY=(*itx)->m_loggedInPlayer->GetPositionY();
					(*itx)->m_loggedInPlayer->m_bgEntryPointZ=(*itx)->m_loggedInPlayer->GetPositionZ();
					(*itx)->m_loggedInPlayer->m_bgEntryPointMap=(*itx)->m_loggedInPlayer->GetMapId();
				}
			}

			pGroup->Unlock();

			m_queueLock.Acquire();
			m_queuedGroups[BattlegroundType].push_back(pGroup->GetID());
			m_queueLock.Release();
			Log.Success("BattlegroundMgr", "Group %u is now in battleground queue for arena type %u", pGroup->GetID(), BattlegroundType);

			/* send the battleground status packet */

			return;
		}
	}
	

	/* Queue him! */
	m_queueLock.Acquire();
	m_queuedPlayers[BattlegroundType][lgroup].push_back(pguid);
	Log.Success("BattlegroundMgr", "Player %u is now in battleground queue for {Arena %u}", m_session->GetPlayer()->GetLowGUID(), BattlegroundType );

	/* send the battleground status packet */
	SendBattlefieldStatus(m_session->GetPlayer(), 1, BattlegroundType, 0 , 0, 0,0);
	m_session->GetPlayer()->m_bgIsQueued = true;
	m_session->GetPlayer()->m_bgQueueInstanceId = 0;
	m_session->GetPlayer()->m_bgQueueType = BattlegroundType;

	/* Set battleground entry point */
	m_session->GetPlayer()->m_bgEntryPointX = m_session->GetPlayer()->GetPositionX();
	m_session->GetPlayer()->m_bgEntryPointY = m_session->GetPlayer()->GetPositionY();
	m_session->GetPlayer()->m_bgEntryPointZ = m_session->GetPlayer()->GetPositionZ();
	m_session->GetPlayer()->m_bgEntryPointMap = m_session->GetPlayer()->GetMapId();
	m_session->GetPlayer()->m_bgEntryPointInstance = m_session->GetPlayer()->GetInstanceID();

	m_queueLock.Release();
}
예제 #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;
}
예제 #7
0
void CBattlegroundManager::EventQueueUpdate()
{
	deque<Player*> tempPlayerVec[2];
	uint32 i,j,k;
	Player * plr;
	CBattleground * bg;
	list<uint32>::iterator it3, it4;
	//vector<Player*>::iterator it6;
	map<uint32, CBattleground*>::iterator iitr;
	Arena * arena;
	int32 team;
	m_queueLock.Acquire();
	m_instanceLock.Acquire();

	for(i = 0; i < BATTLEGROUND_NUM_TYPES; ++i)
	{
		for(j = 0; j < MAX_LEVEL_GROUP; ++j)
		{
			if(!m_queuedPlayers[i][j].size())
				continue;

			tempPlayerVec[0].clear();
			tempPlayerVec[1].clear();

			for(it3 = m_queuedPlayers[i][j].begin(); it3 != m_queuedPlayers[i][j].end();)
			{
				it4 = it3++;
                plr = objmgr.GetPlayer(*it4);
				
				if(!plr || GetLevelGrouping(plr->getLevel()) != j)
				{
                    m_queuedPlayers[i][j].erase(it4);
					continue;
				}

				// queued to a specific instance id?
				if(plr->m_bgQueueInstanceId != 0)
				{
					iitr = m_instances[i].find(plr->m_bgQueueInstanceId);
					if(iitr == m_instances[i].end())
					{
						// queue no longer valid
						plr->GetSession()->SystemMessage("Your queue on battleground instance id %u is no longer valid. Reason: Instance Deleted.", plr->m_bgQueueInstanceId);
						plr->m_bgIsQueued = false;
						plr->m_bgQueueType = 0;
						plr->m_bgQueueInstanceId = 0;
						m_queuedPlayers[i][j].erase(it4);
					}

					// can we join?
					bg = iitr->second;
					if(bg->CanPlayerJoin(plr))
					{
						bg->AddPlayer(plr, plr->GetTeam());
						m_queuedPlayers[i][j].erase(it4);
					}
				}
				else
				{
					if(IS_ARENA(i))
						tempPlayerVec[0].push_back(plr);
					else
						tempPlayerVec[plr->GetTeam()].push_back(plr);
				}
			}

			// try to join existing instances
			for(iitr = m_instances[i].begin(); iitr != m_instances[i].end(); ++iitr)
			{
				if( iitr->second->HasEnded() || iitr->second->GetLevelGroup() != j)
					continue;

				if(IS_ARENA(i))
				{
                    arena = ((Arena*)iitr->second);
					if(arena->Rated())
						continue;

					team = arena->GetFreeTeam();
					while(team >= 0 && tempPlayerVec[0].size())
					{
						plr = *tempPlayerVec[0].begin();
						tempPlayerVec[0].pop_front();
						plr->m_bgTeam=team;
						arena->AddPlayer(plr, team);
						ErasePlayerFromList(plr->GetLowGUID(), &m_queuedPlayers[i][j]);
						team = arena->GetFreeTeam();
					}
				}
				else
				{
					bg = iitr->second;
					for(k = 0; k < 2; ++k)
					{
						while(tempPlayerVec[k].size() && bg->HasFreeSlots(k))
						{
							plr = *tempPlayerVec[k].begin();
							tempPlayerVec[k].pop_front();
							bg->AddPlayer(plr, plr->GetTeam());
							ErasePlayerFromList(plr->GetLowGUID(), &m_queuedPlayers[i][j]);
						}
					}
				}
			}

			if(IS_ARENA(i))
			{
				// enough players to start a round?
				if(tempPlayerVec[0].size() < BGMinimumPlayers[i])
					continue;

				if(CanCreateInstance(i,j))
				{
					arena = ((Arena*)CreateInstance(i, j));
					team = arena->GetFreeTeam();
					while(!arena->IsFull() && tempPlayerVec[0].size() && team >= 0)
					{
						plr = *tempPlayerVec[0].begin();
						tempPlayerVec[0].pop_front();

						plr->m_bgTeam=team;
						arena->AddPlayer(plr, team);
						team = arena->GetFreeTeam();

						// remove from the main queue (painful!)
						ErasePlayerFromList(plr->GetLowGUID(), &m_queuedPlayers[i][j]);
					}
				}
			}
			else
			{
#ifdef ONLY_ONE_PERSON_REQUIRED_TO_JOIN_DEBUG
				if(tempPlayerVec[0].size() >= 1 ||
					tempPlayerVec[1].size() >= 1)
#else
				if(tempPlayerVec[0].size() >= BGMinimumPlayers[i] &&
					tempPlayerVec[1].size() >= BGMinimumPlayers[i])
#endif
				{
					if(CanCreateInstance(i,j))
					{
						bg = CreateInstance(i,j);
						if( bg == NULL )
						{
							// creation failed
							for(k = 0; k < 2; ++k)
							{
								while(tempPlayerVec[k].size())
								{
									plr = *tempPlayerVec[k].begin();
									tempPlayerVec[k].pop_front();
									ErasePlayerFromList(plr->GetLowGUID(), &m_queuedPlayers[i][j]);
								}
							}
						}
						else
						{						
							// push as many as possible in
							for(k = 0; k < 2; ++k)
							{
								while(tempPlayerVec[k].size() && bg->HasFreeSlots(k))
								{
									plr = *tempPlayerVec[k].begin();
									tempPlayerVec[k].pop_front();
									plr->m_bgTeam=k;
									bg->AddPlayer(plr, k);
									ErasePlayerFromList(plr->GetLowGUID(), &m_queuedPlayers[i][j]);
								}
							}
						}
					}
				}
			}
		}
	}

	/* Handle paired arena team joining */
	list<uint32>::iterator itz;
	list<uint32>::iterator itp;
	for(i = BATTLEGROUND_ARENA_2V2; i < BATTLEGROUND_ARENA_5V5+1; ++i)
	{
		// We need at least this many :(
		if(m_queuedGroups[i].size() < 2)
			continue;

		list<uint32> removegroups;
		for(itz = m_queuedGroups[i].begin(); itz != m_queuedGroups[i].end(); itz++)
		{
			Group * pGroup = objmgr.GetGroupById(*itz);
			if(!pGroup || !pGroup->m_isqueued || !pGroup->GetLeader() || pGroup->GetLeader()->arenaTeam[i - 4] == NULL) continue;

			uint32 maxRange = pGroup->GetLeader()->arenaTeam[i - 4]->m_queueSearchRange;
			pGroup->GetLeader()->arenaTeam[i - 4]->m_queueSearchRange += 100;

			vector<uint32> inRangeGroups;

			uint32 rating = pGroup->GetLeader()->arenaTeam[i - 4]->m_stat_rating;
			for(itp = m_queuedGroups[i].begin(); itp != m_queuedGroups[i].end();)
			{
				Group * tGrp = objmgr.GetGroupById(*itp);
				if(!tGrp || !tGrp->m_isqueued || !tGrp->GetLeader() || tGrp->GetLeader()->arenaTeam[i - 4] == NULL)
				{
					itp = m_queuedGroups[i].erase(itp);
					continue;
				}

				++itp;

				if( pGroup == tGrp )
					continue;

				uint32 tRating = tGrp->GetLeader()->arenaTeam[i - 4]->m_stat_rating;

				int32 diff = (int32)tRating - (int32)rating;
				if(diff < 0)
					diff = -diff;

				if(diff > (int32)maxRange)
					continue;

				//Log.Notice("Debug", "EventQueueUpdate added 1 in range arena");

				inRangeGroups.push_back(tGrp->GetID());
			}

			// K, we have a giant list of groups that we could group with, hopefully!
			// or not, we can't go on :(
			if(!inRangeGroups.size())
				continue;

			// But if we're here, we can :D
			uint32 r = 0;
			if( inRangeGroups.size() > 1 )
				r = RandomUInt((uint32)inRangeGroups.size() - 1);

			Group * pairGroup = objmgr.GetGroupById(inRangeGroups[r]);
			if(!pairGroup) continue;

			// Now, let's create this rated Arena Match :)

			//Log.Notice("Debug", "EventQueueUpdate creating arena");
			Arena * arena = (Arena*)CreateInstance(i, LEVEL_GROUP_70);
			ArenaTeam *pTeamPair[2];

			if(arena)
			{
				//Log.Notice("Debug", "EventQueueUpdate arena created");
				removegroups.push_back(pGroup->GetID());
				removegroups.push_back(pairGroup->GetID());
				pGroup->m_isqueued = false;
				pairGroup->m_isqueued = false;
				arena->rated_match = true;
				if( pGroup->GetLeader()->arenaTeam[i - 4] != NULL )
				{
					arena->m_ratedTeams[0] = pGroup->GetLeader()->arenaTeam[i - 4]->m_id;
					pTeamPair[0] = pGroup->GetLeader()->arenaTeam[i - 4];
				}
				else
					pTeamPair[0] = NULL;
				
				if( pairGroup->GetLeader()->arenaTeam[i - 4] != NULL )
				{
					arena->m_ratedTeams[1] = pairGroup->GetLeader()->arenaTeam[i - 4]->m_id;
					pTeamPair[1] = pairGroup->GetLeader()->arenaTeam[i - 4];
				}
				else
					pTeamPair[1] = NULL;

				pGroup->GetLeader()->arenaTeam[i - 4]->m_queueSearchRange = 100;
				pairGroup->GetLeader()->arenaTeam[i - 4]->m_queueSearchRange = 100;
				GroupMembersSet::iterator gitr;
				pGroup->Lock();
				for(gitr = pGroup->GetSubGroup(0)->GetGroupMembersBegin(); gitr != pGroup->GetSubGroup(0)->GetGroupMembersEnd(); gitr++)
				{
					PlayerInfo * pi = (*gitr);
					if(!pi->m_loggedInPlayer)
						continue;

					//Log.Notice("Debug", "EventQueueUpdate player lewp");
					pi->m_loggedInPlayer->m_bgTeam = 0;
					if(arena->HasFreeSlots(0))
					{
						arena->AddPlayer(pi->m_loggedInPlayer, 0);
						arena->m_RatedPlayers[0].insert(pi);
						if( pTeamPair[0] != NULL )
						{
							ArenaTeamMember * atm = pTeamPair[0]->GetMember(pi);
							if(atm)
							{
								atm->Played_ThisSeason++;
								atm->Played_ThisWeek++;
							}
							//Log.Notice("Debug", "EventQueueUpdate added player %s", pi->m_loggedInPlayer->GetName());
						}
					}
				}
				pGroup->Unlock();
				pairGroup->Lock();
				for(gitr = pairGroup->GetSubGroup(0)->GetGroupMembersBegin(); gitr != pairGroup->GetSubGroup(0)->GetGroupMembersEnd(); gitr++)
				{
					PlayerInfo * pi = (*gitr);
					if(!pi->m_loggedInPlayer || pi->arenaTeam[i-4] == NULL)
						continue;

					pi->m_loggedInPlayer->m_bgTeam = 1;
					if(arena->HasFreeSlots(1))
					{
						arena->AddPlayer(pi->m_loggedInPlayer, 1);
						arena->m_RatedPlayers[1].insert(pi);
						if( pTeamPair[1] != NULL )
						{
							ArenaTeamMember * atm = pTeamPair[1]->GetMember(pi);
							if(atm)
							{
								atm->Played_ThisSeason++;
								atm->Played_ThisWeek++;
							}
						}
					}
				}
				pairGroup->Unlock();
			}
		}


		for(itz = removegroups.begin(); itz != removegroups.end(); itz++)
		{
			m_queuedGroups[i].remove(*itz);
		}
	}

	m_queueLock.Release();
	m_instanceLock.Release();
}
예제 #8
0
uint32 InstanceMgr::PreTeleport(uint32 mapid, Player * plr, uint32 instanceid)
{
	// preteleport is where all the magic happens :P instance creation, etc.
	MapInfo * inf = WorldMapInfoStorage.LookupEntry(mapid);
	Group * pGroup;
	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;

	// players without groups cannot enter raid instances (no soloing them:P)
	if(plr->GetGroup() == NULL && (inf->type == INSTANCE_RAID || inf->type == INSTANCE_MULTIMODE) && !plr->triggerpass_cheat)
		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];

	// set up our pointers (cleaner code is always good)
	pGroup = plr->GetGroup();

	if(instancemap == NULL)
	{
		if(instanceid != 0)
		{
			m_mapLock.Release();
			return INSTANCE_ABORT_NOT_FOUND;
		}

		// gotta create the hashmap.
		m_instances[mapid] = new InstanceMap;
		instancemap = m_instances[mapid];
	}
	else
	{
		InstanceMap::iterator itr;
		if(instanceid != 0)
		{
			itr = instancemap->find(instanceid);
			if(itr != instancemap->end()) {
				m_mapLock.Release();
				return INSTANCE_OK;
			} else {
				m_mapLock.Release();
				return INSTANCE_ABORT_NOT_FOUND;
			}
		}
		else
		{
			// search the instance and see if we have one here.
			for(itr = instancemap->begin(); itr != instancemap->end();)
			{
				in = itr->second;
				++itr;
				if(PlayerOwnsInstance(in, plr))
				{
					m_mapLock.Release();

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

						if(in->m_mapMgr->GetPlayerCount() >= inf->playerlimit)
							return INSTANCE_ABORT_FULL;
					}

					// found our instance, allow him in.
					return INSTANCE_OK;
				}
			}
		}
	}

	// if we're here, it means we need to create a new instance.
	in = new Instance;
	in->m_creation = UNIXTIME;
	in->m_expiration =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 = NULL;		// always start off without a map manager, it is created in GetInstance()
	in->m_mapInfo = inf;
	in->m_isBattleground=false;
	plr->SetInstanceID(in->m_instanceId);
	Log.Debug("InstanceMgr", "Creating instance for player %u and group %u on map %u. (%u)", in->m_creatorGuid, in->m_creatorGroup, in->m_mapId, in->m_instanceId);
	
	// save our new instance to the database.
	in->SaveToDB();
	
	// apply it in the instance map
	instancemap->insert( InstanceMap::value_type( in->m_instanceId, in ) );

	// instance created ok, i guess? return the ok for him to transport.
	m_mapLock.Release();
	return INSTANCE_OK;
}
예제 #9
0
bool ChatHandler::HandleResetInstanceCommand(const char* args, WorldSession *m_session)
{
	uint32 instanceId = (args ? atoi(args) : 0);
	if(instanceId == 0)
		return false;

	Player * plr = getSelectedChar(m_session, true);
	if(!plr)
		return true;

	Instance *instance = sInstanceMgr.GetInstanceByIds(NUM_MAPS, instanceId);
	if(instance == NULL)
	{
		RedSystemMessage(m_session, "There's no instance with id %u.", instanceId);
		return true;
	}

	if(IS_PERSISTENT_INSTANCE(instance))
	{
		if(m_session->CanUseCommand('z'))
		{
			bool foundSomething = false;
			plr->m_playerInfo->savedInstanceIdsLock.Acquire();
			for(int difficulty=0; difficulty<NUM_INSTANCE_MODES; difficulty++)
			{
				PlayerInstanceMap::iterator itr = plr->m_playerInfo->savedInstanceIds[difficulty].find(instance->m_mapId);
				if(itr == plr->m_playerInfo->savedInstanceIds[difficulty].end() || (*itr).second != instance->m_instanceId)
					continue;
				plr->SetPersistentInstanceId(instance->m_mapId, difficulty, 0);
				SystemMessage(m_session, "Instance with id %u (%s) is persistent and will only be revoked from player.", instanceId, GetDifficultyString(difficulty));
				foundSomething = true;
			}
			plr->m_playerInfo->savedInstanceIdsLock.Release();
			if(!foundSomething)
				RedSystemMessage(m_session, "Player is not assigned to persistent instance with id %u.", instanceId);
			return true;
		}
		else
		{
			RedSystemMessage(m_session, "Instance with id %u is persistent and can only be removed from player by admins.", instanceId);
			return true;
		}
	}

	if(instance->m_mapMgr && instance->m_mapMgr->HasPlayers())
	{
		RedSystemMessage(m_session, "Failed to reset non-persistent instance with id %u, due to player still inside.", instanceId);
		return true;
	}

	if(instance->m_creatorGroup)
	{
		Group *group = plr->GetGroup();
		if(group == NULL || instance->m_creatorGroup != group->GetID())
		{
			RedSystemMessage(m_session, "Player %s is not a member of the group assigned to the non-persistent instance with id %u.", plr->GetName(), instanceId);
			return true;
		}
	}
	else if(instance->m_creatorGuid == 0 || instance->m_creatorGuid != plr->GetLowGUID())
	{
		RedSystemMessage(m_session, "Player %s is not assigned to instance with id %u.", plr->GetName(), instanceId);
		return true;
	}

	//TODO: Reset that instance...^^
	RedSystemMessage(m_session, "Resetting single non-persistent instances is not available yet.");
	sGMLog.writefromsession(m_session, "used reset instance command on %s, instance %u,", plr->GetName(), instanceId);
	return true;
}
예제 #10
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;
}
예제 #11
0
////////////////////////////////////////////////////////////////
///This function handles CMSG_GROUP_ACCEPT and deny:
////////////////////////////////////////////////////////////////
void WorldSession::HandleGroupAcceptOpcode( WorldPacket & recv_data )
{
	if(!_player->IsInWorld()) 
	{ 
		return;
	}

	uint8 packet_type;
	recv_data >> packet_type;
	if( packet_type == 0 ) //0x80 for group accept and 0 is for decline
	{
		HandleGroupDeclineOpcode( recv_data );
		return;
	}

	Player *player = objmgr.GetPlayer(_player->GetInviter());
	if ( !player )
	{ 
		return;
	}

	//check if this invite is still valid
	if( player->GetInviter() != _player->GetLowGUID() || _player->GetInviter() != player->GetLowGUID() )
	{
		_player->BroadcastMessage( "Group invite from player %s expired", player->GetName() );
		player->BroadcastMessage( "Group invite from player %s expired", _player->GetName() );
		return;
	}
	
	player->SetInviter(0);
	_player->SetInviter(0);
	
	Group *grp = player->GetGroup();

	if(grp)
	{
		grp->AddMember(_player->m_playerInfo);
		_player->dungeon_difficulty = grp->dungeon_difficulty;
		_player->raid_difficulty = grp->raid_difficulty;
		_player->SendDungeonDifficulty();
		_player->SendRaidDifficulty();

        //sInstanceSavingManager.ResetSavedInstancesForPlayer(_player);
		return;
	}
	
	// If we're this far, it means we have no existing group, and have to make one.
	grp = new Group(true);
	grp->dungeon_difficulty = player->dungeon_difficulty;
	grp->raid_difficulty = player->raid_difficulty;
	grp->AddMember(player->m_playerInfo);		// add the inviter first, therefore he is the leader
	grp->AddMember(_player->m_playerInfo);	   // add us.
	_player->dungeon_difficulty = grp->dungeon_difficulty;
	_player->raid_difficulty = grp->raid_difficulty;
	_player->SendDungeonDifficulty();
	_player->SendRaidDifficulty();

	Instance *instance = sInstanceMgr.GetInstanceByIds(player->GetMapId(), player->GetInstanceID());
	if(instance != NULL && instance->m_creatorGuid == player->GetLowGUID())
	{
		grp->AddSavedInstance(instance->m_mapId,instance->instance_difficulty,instance->m_instanceId);
		instance->m_creatorGroup = grp->GetID();
		instance->m_creatorGuid = 0;
		instance->SaveToDB();
	}

    //sInstanceSavingManager.ResetSavedInstancesForPlayer(_player);

	// Currentgroup and all that shit are set by addmember.
}
예제 #12
0
void CBattlegroundManager::RemovePlayerFromQueues(Player* plr)
{
    m_queueLock.Acquire();

    ARCEMU_ASSERT(plr->m_bgQueueType < BATTLEGROUND_NUM_TYPES);

    sEventMgr.RemoveEvents(plr, EVENT_BATTLEGROUND_QUEUE_UPDATE);

    uint32 lgroup = GetLevelGrouping(plr->getLevel());
    list<uint32>::iterator itr;

    itr = m_queuedPlayers[plr->m_bgQueueType][lgroup].begin();
    while (itr != m_queuedPlayers[plr->m_bgQueueType][lgroup].end())
    {
        if ((*itr) == plr->GetLowGUID())
        {
            Log.Debug("BattlegroundManager", "Removing player %u from queue instance %u type %u", plr->GetLowGUID(), plr->m_bgQueueInstanceId, plr->m_bgQueueType);
            m_queuedPlayers[plr->m_bgQueueType][lgroup].erase(itr);
            break;
        }

        ++itr;
    }

    plr->m_bgIsQueued = false;
    plr->m_bgTeam = plr->GetTeam();
    plr->m_pendingBattleground = NULL;
    SendBattlefieldStatus(plr, BGSTATUS_NOFLAGS, 0, 0, 0, 0, 0);
    m_queueLock.Release();

    Group* group;
    group = plr->GetGroup();
    if (group)  //if da n****s in a group, boot dis bitch ass' group outa da q
    {
        Log.Debug("BattlegroundManager", "Player %u removed whilst in a group. Removing players group %u from queue", plr->GetLowGUID(), group->GetID());
        RemoveGroupFromQueues(group);
    }
}
예제 #13
0
void CBattlegroundManager::HandleArenaJoin(WorldSession* m_session, uint32 BattlegroundType, uint8 as_group, uint8 rated_match)
{
    uint32 pguid = m_session->GetPlayer()->GetLowGUID();
    uint32 lgroup = GetLevelGrouping(m_session->GetPlayer()->getLevel());
    if (as_group && m_session->GetPlayer()->GetGroup() == NULL)
        return;

    Group* pGroup = m_session->GetPlayer()->GetGroup();
    if (as_group)
    {
        if (pGroup->GetSubGroupCount() != 1)
        {
            m_session->SystemMessage(m_session->LocalizedWorldSrv(55));
            return;
        }
        if (pGroup->GetLeader() != m_session->GetPlayer()->getPlayerInfo())
        {
            m_session->SystemMessage(m_session->LocalizedWorldSrv(56));
            return;
        }

        GroupMembersSet::iterator itx;
        if (!rated_match)
        {
            /* add all players normally.. bleh ;P */
            pGroup->Lock();
            for (itx = pGroup->GetSubGroup(0)->GetGroupMembersBegin(); itx != pGroup->GetSubGroup(0)->GetGroupMembersEnd(); ++itx)
            {
                if ((*itx)->m_loggedInPlayer && !(*itx)->m_loggedInPlayer->m_bgIsQueued && !(*itx)->m_loggedInPlayer->m_bg)
                    HandleArenaJoin((*itx)->m_loggedInPlayer->GetSession(), BattlegroundType, 0, 0);
            }
            pGroup->Unlock();
            return;
        }
        else
        {
            /* make sure all players are 70 */
            uint32 maxplayers;
            uint32 type = BattlegroundType - BATTLEGROUND_ARENA_2V2;
            switch (BattlegroundType)
            {
                case BATTLEGROUND_ARENA_3V3:
                    maxplayers = 3;
                    break;

                case BATTLEGROUND_ARENA_5V5:
                    maxplayers = 5;
                    break;

                case BATTLEGROUND_ARENA_2V2:
                default:
                    maxplayers = 2;
                    break;
            }

            if (pGroup->GetLeader()->m_loggedInPlayer && pGroup->GetLeader()->m_loggedInPlayer->m_arenaTeams[type] == NULL)
            {
                m_session->SendNotInArenaTeamPacket(uint8(maxplayers));
                return;
            }

            pGroup->Lock();
            for (itx = pGroup->GetSubGroup(0)->GetGroupMembersBegin(); itx != pGroup->GetSubGroup(0)->GetGroupMembersEnd(); ++itx)
            {
                if (maxplayers == 0)
                {
                    m_session->SystemMessage(m_session->LocalizedWorldSrv(58));
                    pGroup->Unlock();
                    return;
                }

                if ((*itx)->lastLevel < PLAYER_ARENA_MIN_LEVEL)
                {
                    m_session->SystemMessage(m_session->LocalizedWorldSrv(59));
                    pGroup->Unlock();
                    return;
                }

                if ((*itx)->m_loggedInPlayer)
                {
                    if ((*itx)->m_loggedInPlayer->m_bg || (*itx)->m_loggedInPlayer->m_bgIsQueued)
                    {
                        m_session->SystemMessage(m_session->LocalizedWorldSrv(60));
                        pGroup->Unlock();
                        return;
                    };
                    if ((*itx)->m_loggedInPlayer->m_arenaTeams[type] != pGroup->GetLeader()->m_loggedInPlayer->m_arenaTeams[type])
                    {
                        m_session->SystemMessage(m_session->LocalizedWorldSrv(61));
                        pGroup->Unlock();
                        return;
                    }

                    --maxplayers;
                }
            }
            WorldPacket data(SMSG_GROUP_JOINED_BATTLEGROUND, 4);
            data << uint32(6);      // all arenas

            for (itx = pGroup->GetSubGroup(0)->GetGroupMembersBegin(); itx != pGroup->GetSubGroup(0)->GetGroupMembersEnd(); ++itx)
            {
                if ((*itx)->m_loggedInPlayer)
                {
                    SendBattlefieldStatus((*itx)->m_loggedInPlayer, BGSTATUS_INQUEUE, BattlegroundType, 0, 0, 0, 1);
                    (*itx)->m_loggedInPlayer->m_bgIsQueued = true;
                    (*itx)->m_loggedInPlayer->m_bgQueueInstanceId = 0;
                    (*itx)->m_loggedInPlayer->m_bgQueueType = BattlegroundType;
                    (*itx)->m_loggedInPlayer->GetSession()->SendPacket(&data);
                    (*itx)->m_loggedInPlayer->m_bgEntryPointX = (*itx)->m_loggedInPlayer->GetPositionX();
                    (*itx)->m_loggedInPlayer->m_bgEntryPointY = (*itx)->m_loggedInPlayer->GetPositionY();
                    (*itx)->m_loggedInPlayer->m_bgEntryPointZ = (*itx)->m_loggedInPlayer->GetPositionZ();
                    (*itx)->m_loggedInPlayer->m_bgEntryPointMap = (*itx)->m_loggedInPlayer->GetMapId();
                }
            }

            pGroup->Unlock();

            m_queueLock.Acquire();
            m_queuedGroups[BattlegroundType].push_back(pGroup->GetID());
            m_queueLock.Release();
            Log.Notice("BattlegroundMgr", "Group %u is now in battleground queue for arena type %u", pGroup->GetID(), BattlegroundType);

            /* send the battleground status packet */

            return;
        }
    }


    /* Queue him! */
    m_queueLock.Acquire();
    m_queuedPlayers[BattlegroundType][lgroup].push_back(pguid);
    Log.Notice("BattlegroundMgr", "Player %u is now in battleground queue for {Arena %u}", m_session->GetPlayer()->GetLowGUID(), BattlegroundType);

    /* send the battleground status packet */
    SendBattlefieldStatus(m_session->GetPlayer(), BGSTATUS_INQUEUE, BattlegroundType, 0, 0, 0, 0);
    m_session->GetPlayer()->m_bgIsQueued = true;
    m_session->GetPlayer()->m_bgQueueInstanceId = 0;
    m_session->GetPlayer()->m_bgQueueType = BattlegroundType;

    /* Set battleground entry point */
    m_session->GetPlayer()->m_bgEntryPointX = m_session->GetPlayer()->GetPositionX();
    m_session->GetPlayer()->m_bgEntryPointY = m_session->GetPlayer()->GetPositionY();
    m_session->GetPlayer()->m_bgEntryPointZ = m_session->GetPlayer()->GetPositionZ();
    m_session->GetPlayer()->m_bgEntryPointMap = m_session->GetPlayer()->GetMapId();
    m_session->GetPlayer()->m_bgEntryPointInstance = m_session->GetPlayer()->GetInstanceID();

    m_queueLock.Release();
}
예제 #14
0
//Yeahlight: Searches for the group that will be rewarded with exp and first loot rights
returnGroup HateList::GetRewardingGroup()
{
	groupDamage groupsToConsider[255] = {0};
	int16 groupCounter = 0;
	int16 groupID = 0;
	int16 leadingGroupID = 0;
	sint32 highestGroupDamage = 0;
	sint32 entityDamage = 0;
	Mob* entity = NULL;
	returnGroup groupToReward;
	Group* group = NULL;
	bool groupFound = false;

	for(int i = 0; i < 255; i++)
	{
		groupsToConsider[i].groupID = -1;
		groupsToConsider[i].groupDamageTotal = -1;
	}
	groupToReward.damage = 0;
	groupToReward.group = NULL;

	LinkedListIterator<tHateEntry*> iterator(list);
    iterator.Reset();
	while(iterator.MoreElements())
    {
		entityDamage = 0;
		if(iterator.GetData())
			entityDamage = iterator.GetData()->damage;
		if(entityDamage > 0)
		{
			entity = iterator.GetData()->ent;
			//Yeahlight: Entity exists in the zone
			if(entity)
			{
				//Yeahlight: Entity is a client
				if(entity->IsClient())
				{
					//Yeahlight: PC is grouped
					if(entity->CastToClient()->IsGrouped())
					{
						group = entity_list.GetGroupByClient(entity->CastToClient());
						//Yeahlight: Group exists
						if(group)
						{
							groupID = group->GetID();
							//Yeahlight: We do not have a group list started yet, so start it off with this group
							if(groupCounter == 0)
							{
								groupsToConsider[0].groupID = groupID;
								groupsToConsider[0].groupDamageTotal = iterator.GetData()->damage;
								groupsToConsider[0].group = group;
								groupCounter++;
							}
							//Yeahlight: A group list has been created already
							else
							{
								//Yeahlight: Iterate through the group list
								for(int i = 0; i < groupCounter; i++)
								{
									//Yeahlight: Found the group for which this PC resides
									if(groupID == groupsToConsider[i].groupID)
									{
										//Yeahlight: Add the client's damage to the group's total
										groupsToConsider[i].groupDamageTotal += iterator.GetData()->damage;
										//Yeahlight: Flag the PC as found
										groupFound = true;
										//Yeahlight: "Break out" of the loop
										i = groupCounter;
									}
								}
								//Yeahlight: This grouped PC did not find their group in the list, so we need to add their group
								if(!groupFound)
								{
									groupsToConsider[groupCounter].groupID = groupID;
									groupsToConsider[groupCounter].groupDamageTotal = iterator.GetData()->damage;
									groupsToConsider[groupCounter].group = group;
									groupCounter++;
								}
							}
						}
						//Yeahlight: Group does not exist
						else
						{
							
						}
					}
					//Yeahlight: PC is not grouped
					else
					{

					}
				}
				//Yeahlight: Entity is the pet of a client
				else if(entity->IsNPC() && entity->GetOwner() && entity->GetOwner()->IsClient())
				{
					//Yeahlight: Owner of the pet is grouped
					if(entity->GetOwner()->CastToClient()->IsGrouped())
					{
						group = entity_list.GetGroupByClient(entity->GetOwner()->CastToClient());
						//Yeahlight: Group exists
						if(group)
						{
							groupID = group->GetID();
							//Yeahlight: We do not have a group list started yet, so start it off with this group
							if(groupCounter == 0)
							{
								groupsToConsider[0].groupID = groupID;
								groupsToConsider[0].groupDamageTotal = iterator.GetData()->damage;
								groupsToConsider[0].group = group;
								groupCounter++;
							}
							//Yeahlight: A group list has been created already
							else
							{
								//Yeahlight: Iterate through the group list
								for(int i = 0; i < groupCounter; i++)
								{
									//Yeahlight: Found the group for which this pet resides
									if(groupID == groupsToConsider[i].groupID)
									{
										//Yeahlight: Add the pet's damage to the group's total
										groupsToConsider[i].groupDamageTotal += iterator.GetData()->damage;
										//Yeahlight: Flag the pet as found
										groupFound = true;
										//Yeahlight: "Break out" of the loop
										i = groupCounter;
									}
								}
								//Yeahlight: This grouped pet did not find their group in the list, so we need to add their group
								if(!groupFound)
								{
									groupsToConsider[groupCounter].groupID = groupID;
									groupsToConsider[groupCounter].groupDamageTotal = iterator.GetData()->damage;
									groupsToConsider[groupCounter].group = group;
									groupCounter++;
								}
							}
						}
						//Yeahlight: Group does not exist
						else
						{
							
						}
					}
					//Yeahlight: Pet's owner is not grouped
					else
					{

					}
				}
			}
			//Yeahlight: Entity does not exist in the zone
			else
			{

			}
		}
        iterator.Advance();
		//Yeahlight: Zone freeze debug
		if(ZONE_FREEZE_DEBUG && rand()%ZONE_FREEZE_DEBUG == 1)
			EQC_FREEZE_DEBUG(__LINE__, __FILE__);
    }

	//Yeahlight: Iterate through the group list and record for the highest damaging group
	for(int i = 0; i < groupCounter; i++)
	{
		//Yeahlight: Found a group with more total damage than our current leader
		if(groupsToConsider[i].groupDamageTotal > highestGroupDamage)
		{
			highestGroupDamage = groupsToConsider[i].groupDamageTotal;
			groupToReward.damage = groupsToConsider[i].groupDamageTotal;
			groupToReward.group = groupsToConsider[i].group;
		}
	}

	return groupToReward;
}
예제 #15
0
void InstanceMgr::ResetSavedInstances(Player * plr)
{
    WorldPacket *pData;
    Instance * in;
    InstanceMap::iterator itr;
    InstanceMap * instancemap;
    uint32 i;

    if (!plr->IsInWorld() || plr->GetMapMgr()->GetMapInfo()->type != INSTANCE_NULL)
        return;

    m_mapLock.Acquire();
    Group *group = plr->GetGroup();
    for (i = 0; i < NUM_MAPS; ++i)
    {
        if (m_instances[i] != NULL)
        {
            instancemap = m_instances[i];
            for (itr = instancemap->begin(); itr != instancemap->end();)
            {
                in = itr->second;
                ++itr;

                if (IS_RESETABLE_INSTANCE(in) && ((group && group->GetID() == in->m_creatorGroup) || plr->GetLowGUID() == in->m_creatorGuid))
                {
                    if (in->m_mapMgr && in->m_mapMgr->HasPlayers())
                    {
                        pData = new WorldPacket(SMSG_INSTANCE_RESET_FAILED, 8);
                        *pData << uint32(INSTANCE_RESET_ERROR_PLAYERS_INSIDE);
                        *pData << uint32(in->m_mapId);
                        plr->GetSession()->SendPacket(pData);
                        delete pData;
                        continue;
                    }

                    if (group)
                    {
                        group->m_instanceIds[in->m_mapId][in->m_difficulty] = 0;
                    }

                    // <mapid> has been reset.
                    pData = new WorldPacket(SMSG_INSTANCE_RESET, 4);
                    *pData << uint32(in->m_mapId);
                    plr->GetSession()->SendPacket(pData);
                    delete pData;

                    // destroy the instance
                    _DeleteInstance(in, true);
                }
            }
        }
    }
    m_mapLock.Release();
    /*	plr->m_playerInfo->savedInstanceIdsLock.Acquire();
        for(int difficulty=0; difficulty<NUM_INSTANCE_MODES; difficulty++)
        {
        PlayerInstanceMap::iterator itr,itr2=plr->m_playerInfo->savedInstanceIds[difficulty].begin();
        for(; itr2 != plr->m_playerInfo->savedInstanceIds[difficulty].end();)
        {
        itr = itr2;
        itr2++;
        in = sInstanceMgr.GetInstanceByIds((*itr).first, (*itr).second);
        if( !in )
        continue;
        if(((group && group->GetID() == in->m_creatorGroup) || plr->GetLowGUID() == in->m_creatorGuid))
        {
        if(in->m_mapMgr && in->m_mapMgr->HasPlayers())
        {
        pData = new WorldPacket(SMSG_RESET_INSTANCE_FAILED, 8);
        *pData << uint32(INSTANCE_RESET_ERROR_PLAYERS_INSIDE);
        *pData << uint32(in->m_mapId);
        plr->GetSession()->SendPacket(pData);
        delete pData;
        continue;
        }

        if(group)
        {
        group->m_instanceIds[in->m_mapId][in->m_difficulty] = 0;
        }

        // <mapid> has been reset.
        pData = new WorldPacket(SMSG_RESET_INSTANCE, 4);
        *pData << uint32(in->m_mapId);
        plr->GetSession()->SendPacket(pData);
        delete pData;

        //remove instance from player
        plr->SetPersistentInstanceId(in->m_mapId, difficulty, 0);
        // destroy the instance
        _DeleteInstance(in, true);
        }
        }
        }
        plr->m_playerInfo->savedInstanceIdsLock.Release();*/
}
예제 #16
0
uint32 InstanceMgr::PreTeleport(uint32 mapid, Player * plr, uint32 instanceid)
{
    // preteleport is where all the magic happens :P instance creation, etc.
    MapInfo * inf = WorldMapInfoStorage.LookupEntry(mapid);
    Group * pGroup;
    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;

    pGroup = plr->GetGroup();

    // players without groups cannot enter raids and heroic instances
    if (pGroup == NULL && (inf->type == INSTANCE_RAID || (inf->type == INSTANCE_MULTIMODE && plr->iInstanceType >= MODE_HEROIC)) && !plr->TriggerpassCheat)
        return INSTANCE_ABORT_NOT_IN_RAID_GROUP;

    // players without raid groups cannot enter raid instances
    if (pGroup != NULL && pGroup->GetGroupType() != GROUP_TYPE_RAID && inf->type == INSTANCE_RAID && !plr->TriggerpassCheat)
        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 == NULL)
    {
        if (instanceid != 0)
        {
            m_mapLock.Release();
            return INSTANCE_ABORT_NOT_FOUND;
        }

        // gotta create the hashmap.
        m_instances[mapid] = new InstanceMap;
        instancemap = m_instances[mapid];
    }
    else
    {
        InstanceMap::iterator itr;

        if (instanceid != 0)
        {
            itr = instancemap->find(instanceid);
            if (itr != instancemap->end())
            {
                in = itr->second;

                if (!CHECK_INSTANCE_GROUP(in, pGroup))
                {
                    // Another group is already playing in this instance of the dungeon...
                    m_mapLock.Release();
                    sChatHandler.SystemMessageToPlr(plr, "Another group is already inside this instance of the dungeon.");
                    return INSTANCE_ABORT_NOT_IN_RAID_GROUP;
                }

                // Try to add instance ID to player
                plr->SetPersistentInstanceId(in);

                // Set current group
                if (pGroup)
                    in->m_creatorGroup = pGroup->GetID();

                m_mapLock.Release();
                return INSTANCE_OK;
            }
            else
            {
                m_mapLock.Release();
                return INSTANCE_ABORT_NOT_FOUND;
            }
        }
        else
        {
            in = NULL;
            if (pGroup != NULL)
            {
                if ((inf->type == INSTANCE_MULTIMODE && pGroup->m_difficulty >= MODE_HEROIC) || inf->type == INSTANCE_RAID)
                {
                    if (plr->GetPersistentInstanceId(mapid, pGroup->m_difficulty) == 0)
                    {
                        if (pGroup->m_instanceIds[mapid][pGroup->m_difficulty] != 0)
                        {
                            in = sInstanceMgr.GetInstanceByIds(mapid, pGroup->m_instanceIds[mapid][pGroup->m_difficulty]);
                        }
                        else if (sWorld.instance_TakeGroupLeaderID)
                        {
                            PlayerInfo *pLeaderInfo = pGroup->GetLeader();
                            if (pLeaderInfo)
                            {
                                pLeaderInfo->savedInstanceIdsLock.Acquire();
                                PlayerInstanceMap::iterator itrLeader = pLeaderInfo->savedInstanceIds[pGroup->m_difficulty].find(mapid);
                                if (itrLeader != pLeaderInfo->savedInstanceIds[pGroup->m_difficulty].end())
                                {
                                    in = sInstanceMgr.GetInstanceByIds(mapid, (*itrLeader).second);
                                }
                                pLeaderInfo->savedInstanceIdsLock.Release();
                            }
                        }
                    }

                    if (in == NULL && plr->GetPersistentInstanceId(mapid, pGroup->m_difficulty) != 0)
                    {
                        in = sInstanceMgr.GetInstanceByIds(mapid, plr->GetPersistentInstanceId(mapid, pGroup->m_difficulty));
                    }
                }
                else
                {
                    if (pGroup->m_instanceIds[mapid][pGroup->m_difficulty] != 0)
                    {
                        in = sInstanceMgr.GetInstanceByIds(mapid, pGroup->m_instanceIds[mapid][pGroup->m_difficulty]);
                    }
                }
            }

            if (in == NULL)
            {
                // search the instance and see if we have one here.
                for (itr = instancemap->begin(); itr != instancemap->end();)
                {
                    in = itr->second;
                    ++itr;
                    if (in->m_difficulty == plr->iInstanceType && PlayerOwnsInstance(in, plr))
                        break;
                    in = NULL;
                }
            }

            if (in != NULL)
            {
                m_mapLock.Release();

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

                    if (in->m_mapMgr->GetPlayerCount() >= inf->playerlimit)
                        return INSTANCE_ABORT_FULL;
                }

                if (!CHECK_INSTANCE_GROUP(in, pGroup))
                {
                    // Another group is already playing in this instance of the dungeon...
                    sChatHandler.SystemMessageToPlr(plr, "Another group is already inside this instance of the dungeon.");
                    return INSTANCE_ABORT_NOT_IN_RAID_GROUP;
                }

                // Try to add instance ID to player
                plr->SetPersistentInstanceId(in);

                // Set current group
                if (pGroup)
                    in->m_creatorGroup = pGroup->GetID();

                plr->SetInstanceID(in->m_instanceId);

                // found our instance, allow him in.
                return INSTANCE_OK;
            }
        }
    }

    // if we're here, it means we need to create a new instance.
    in = new Instance;
    in->m_creation = UNIXTIME;
    in->m_difficulty = pGroup ? pGroup->m_difficulty : plr->iInstanceType;
    in->m_instanceId = GenerateInstanceID();
    in->m_mapId = mapid;
    in->m_mapInfo = inf;
    in->m_mapMgr = NULL;		// always start off without a map manager, it is created in GetInstance()
    in->m_isBattleground = false;
    in->m_persistent = IS_PERSISTENT_INSTANCE(in) && objmgr.m_InstanceBossInfoMap[mapid] == NULL;
    in->m_creatorGuid = pGroup ? 0 : plr->GetLowGUID();		// creator guid is 0 if its owned by a group.
    in->m_creatorGroup = pGroup ? pGroup->GetID() : 0;
    if (sWorld.instance_SlidingExpiration)
    {
        if (inf->type == INSTANCE_MULTIMODE && in->m_difficulty >= MODE_HEROIC)
            in->m_expiration = UNIXTIME + TIME_DAY;
        else
            in->m_expiration = (inf->type == INSTANCE_NONRAID || (inf->type == INSTANCE_MULTIMODE && in->m_difficulty == MODE_NORMAL)) ? 0 : UNIXTIME + inf->cooldown;
    }
    else
    {
        if (inf->type == INSTANCE_MULTIMODE && in->m_difficulty >= MODE_HEROIC)
        {
            in->m_expiration = UNIXTIME - (UNIXTIME % TIME_DAY) + ((UNIXTIME % TIME_DAY) > (sWorld.instance_DailyHeroicInstanceResetHour * TIME_HOUR) ? 82800 : -3600) + ((sWorld.instance_DailyHeroicInstanceResetHour - sWorld.GMTTimeZone) * TIME_HOUR);
        }
        else if (IS_PERSISTENT_INSTANCE(in))
        {
            if (m_nextInstanceReset[in->m_mapId] == 0)
            {
                m_nextInstanceReset[in->m_mapId] = UNIXTIME - (UNIXTIME % TIME_DAY) - ((sWorld.GMTTimeZone + 1) * TIME_HOUR) + (in->m_mapInfo->cooldown == 0 ? TIME_DAY : in->m_mapInfo->cooldown);
                CharacterDatabase.Execute("REPLACE INTO `server_settings` (`setting_id`, `setting_value`) VALUES ('next_instance_reset_%u', '%u')", in->m_mapId, m_nextInstanceReset[in->m_mapId]);
            }
            if (m_nextInstanceReset[in->m_mapId] + (TIME_MINUTE * 15) < UNIXTIME)
            {
                do
                {
                    time_t tmp = m_nextInstanceReset[in->m_mapId];
                    if (tmp + (TIME_MINUTE * 15) < UNIXTIME)
                        m_nextInstanceReset[in->m_mapId] = tmp + (in->m_mapInfo->cooldown == 0 ? TIME_DAY : in->m_mapInfo->cooldown);
                }
                while (m_nextInstanceReset[in->m_mapId] + (TIME_MINUTE * 15) < UNIXTIME);
                CharacterDatabase.Execute("REPLACE INTO `server_settings` (`setting_id`, `setting_value`) VALUES ('next_instance_reset_%u', '%u')", in->m_mapId, m_nextInstanceReset[in->m_mapId]);
            }
            in->m_expiration = m_nextInstanceReset[in->m_mapId];
        }
        else
        {
            in->m_expiration = (inf->type == INSTANCE_NONRAID || (inf->type == INSTANCE_MULTIMODE && in->m_difficulty == MODE_NORMAL)) ? 0 : UNIXTIME + inf->cooldown;
        }
    }
    plr->SetInstanceID(in->m_instanceId);
    Log.Debug("InstanceMgr", "Creating instance for player %u and group %u on map %u. (%u)", in->m_creatorGuid, in->m_creatorGroup, in->m_mapId, in->m_instanceId);

    // save our new instance to the database.
    in->SaveToDB();

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

    // Try to add instance ID to player
    plr->SetPersistentInstanceId(in);

    // instance created ok, i guess? return the ok for him to transport.
    m_mapLock.Release();
    return INSTANCE_OK;
}