コード例 #1
0
ファイル: AccountCache.cpp プロジェクト: SkyFire/sandshroud
void InformationCore::SendRealms(AuthSocket * Socket)
{
	Realm* realm = NULL;
	HM_NAMESPACE::hash_map<uint32, uint8>::iterator it;
	map<uint32, Realm*>::iterator itr = m_realms.begin();
	if(Socket->GetBuild() <= 6005) // PreBC
	{
		// packet header
		ByteBuffer data(m_realms.size() * 150 + 20);
		data << uint8(0x10);
		data << uint16(0);	  // Size Placeholder

		// dunno what this is..
		data << uint32(0);

		// loop realms :/
		data << uint8(m_realms.size());
		for(; itr != m_realms.end(); ++itr)
		{
			realm = itr->second;

			data << uint32(realm->Icon);
			if(realm->RequiredClient && realm->RequiredClient != Socket->GetBuild())
				data << uint8(REALMCOLOUR_OFFLINE);
			else
				data << uint8(realm->Colour);

			// This part is the same for all.
			data << realm->Name;
			data << realm->Address;
			data << realm->Population;

			/* Get our character count */
			it = realm->CharacterMap.find(Socket->GetAccountID());
			data << uint8( (it == realm->CharacterMap.end()) ? 0 : it->second ); //We can fix this later, character count. 
			data << uint8(realm->WorldRegion);
			if(realm->RequiredClient && realm->RequiredClient != Socket->GetBuild())
				data << uint8(1);
			else
				data << uint8(0);
		}
		realmLock.Release();

		data << uint8(0x15);
		data << uint8(0);

		// Re-calculate size.
#ifdef USING_BIG_ENDIAN
		*(uint16*)&data.contents()[1] = swap16(uint16(data.size() - 3));
#else
		*(uint16*)&data.contents()[1] = uint16(data.size() - 3);
#endif

		// Send to the socket.
		Socket->Send((const uint8*)data.contents(), uint32(data.size()));
		return;
	}

	Account * acct = sAccountMgr.GetAccount(Socket->GetAccountName());
	bool isGM = ( acct ? (acct->GMFlags != NULL) : false );

	realmLock.Acquire();

	// packet header
	ByteBuffer data(m_realms.size() * 150 + 20);
	data << uint8(0x10);
	data << uint16(0);	  // Size Placeholder

	// dunno what this is..
	data << uint32(0);
	size_t count_pos = data.wpos();
	uint16 count = uint16(m_realms.size());
	data << uint16(count);

	// loop realms :/
	for(; itr != m_realms.end(); ++itr)
	{
		realm = itr->second;
		if( !isGM && realm->Population == 0 ) // Crow: Thanks Egari.
		{
			count -= 1;
			realm = NULL;
			continue;
		}

		data << realm->Icon;
		if(realm->RequiredClient && realm->RequiredClient != Socket->GetBuild())
		{
			data << uint8(1);
			data << uint8(REALMCOLOUR_OFFLINE);
		}
		else
		{
			data << realm->Lock;
			data << realm->Colour;
		}

		data << realm->Name;
		data << realm->Address;
		data << realm->Population-1.0f;

		/* Get our character count */
		it = realm->CharacterMap.find(Socket->GetAccountID());
		data << uint8( (it == realm->CharacterMap.end()) ? 0 : it->second );
		data << realm->WorldRegion;
		data << uint8(GetRealmIdByName(realm->Name));		//Realm ID
		realm = NULL;
	}
	realmLock.Release();

	data.put<uint16>(count_pos, count);

	data << uint8(0x17);
	data << uint8(0);

	// Re-calculate size.
	*(uint16*)&data.contents()[1] = uint16(data.size() - 3);

	// Send to the socket.
	Socket->Send((const uint8*)data.contents(), uint32(data.size()));
}
コード例 #2
0
ファイル: AccountCache.cpp プロジェクト: AscEmu/AscEmu_TBC
void InformationCore::SendRealms(AuthSocket* Socket)
{
    realmLock.Acquire();

    // packet header
    ByteBuffer data(m_realms.size() * 150 + 20);
    data << uint8(0x10);
    data << uint16(0);      // Size Placeholder

    // dunno what this is..
    data << uint32(0);

    //sAuthLogonChallenge_C * client = Socket->GetChallenge();
    data << uint16(m_realms.size());

    // loop realms :/
    std::map<uint32, Realm*>::iterator itr = m_realms.begin();
    std::unordered_map<uint32, uint8>::iterator it;
    for(; itr != m_realms.end(); ++itr)
    {
        if (itr->second->GameBuild == Socket->GetChallenge()->build)
        {
            data << uint8(itr->second->Icon);
            data << uint8(itr->second->Lock);        // delete when using data << itr->second->Lock;
            data << uint8(itr->second->flags);

            data << itr->second->Name;
            data << itr->second->Address;
            data << float(itr->second->Population);

            // Get our character count
            it = itr->second->CharacterMap.find(Socket->GetAccountID());
            data << uint8((it == itr->second->CharacterMap.end()) ? 0 : it->second);
            data << uint8(itr->second->TimeZone);
            data << uint8(GetRealmIdByName(itr->second->Name));        //Realm ID
        }
        else // send empty packet for other gameserver which not supports client_build
        {
            data << uint8(0);
            data << uint8(0);        // delete when using data << itr->second->Lock;
            data << uint8(0);

            data << "";
            data << "";
            data << float(0);

            data << uint8(0);
            data << uint8(0);
            data << uint8(GetRealmIdByName(itr->second->Name));        //Realm ID
        }
    }
    data << uint8(0x17);
    data << uint8(0);

    realmLock.Release();

    // Re-calculate size.

    *(uint16*)&data.contents()[1] = uint16(data.size() - 3);

    // Send to the socket.
    Socket->Send((const uint8*)data.contents(), uint32(data.size()));

    std::list< LogonCommServerSocket* > ss;
    std::list< LogonCommServerSocket* >::iterator SSitr;

    ss.clear();

    serverSocketLock.Acquire();

    if(m_serverSockets.empty())
    {
        serverSocketLock.Release();
        return;
    }

    std::set<LogonCommServerSocket*>::iterator itr1;

    // We copy the sockets to a list and call RefreshRealmsPop() from there because if the socket is dead,
    //then calling the method deletes the socket and removes it from the set corrupting the iterator and causing a crash!
    for(itr1 = m_serverSockets.begin(); itr1 != m_serverSockets.end(); ++itr1)
    {
        ss.push_back(*itr1);
    }

    serverSocketLock.Release();

    for(SSitr = ss.begin(); SSitr != ss.end(); ++SSitr)
        (*SSitr)->RefreshRealmsPop();

    ss.clear();
}