예제 #1
0
파일: Packet.cpp 프로젝트: kgrubb/iceee
void PacketManager::ExternalAddPacket(int socket, const char *data,
		int length) {
	if (length == 0) {
		g_Logs.server->error("Cannot add packet of zero size.");
		return;
	}

	Packet packet;
	packet.Assign(data, length);

	GetThread("PacketManager::ExternalAddPacket");
	PendingSocket *pSock = GetPendingSocket(socket);
	if (pSock != NULL)
		pSock->mPacketList.push_back(packet); //Clustering will be performed when the thread grabs and sorts this pending data.
	else
		g_Logs.server->error("Could not retrieve a PendingSocket object.");
	ReleaseThread();
}
예제 #2
0
void SceneryManager::SendPageRequest(const SceneryPageRequest& request, std::list<PacketManager::PACKET_PAIR>& outgoingPackets)
{
	TimeObject to("SceneryManager::SendPageRequest");

	STRINGLIST queryRows;
	Packet data;
	int wpos = 0;
	char idBuf[32];

	GetThread("SceneryManager::HandlePageRequests[page]");

	SceneryPage *page = GetOrCreatePage(request.zone, request.x, request.y);

	if(page == NULL)
	{
		g_Log.AddMessageFormat("[ERROR] SendPageRequest retrieved NULL page");
		
		wpos = PrepExt_QueryResponseNull(prepBuf, request.queryID);
		data.Assign(prepBuf, wpos);
		outgoingPackets.push_back(PacketManager::PACKET_PAIR(request.socket, data));

		ReleaseThread();
		return;
	}

	SceneryPage::SCENERY_IT it;
	for(it = page->mSceneryList.begin(); it != page->mSceneryList.end(); ++it)
	{
		//Build the list of scenery ID strings to form the response to the scenery.list query.
		//No need to save row data unless the query is required.
		if(request.skipQuery == false)
		{
			sprintf(idBuf, "%d", it->second.ID);
			queryRows.push_back(idBuf);
		}
		
		wpos += PrepExt_UpdateScenery(&prepBuf[wpos], &it->second);
		if(wpos > Global::MAX_SEND_CHUNK_SIZE)
		{
			data.Assign(prepBuf, wpos);
			outgoingPackets.push_back(PacketManager::PACKET_PAIR(request.socket, data));
			wpos = 0;
		}
	}
	if(wpos > 0)
	{
		data.Assign(prepBuf, wpos);
		outgoingPackets.push_back(PacketManager::PACKET_PAIR(request.socket, data));
	}

	//Done accessing the scenery data itself, no need to hold the thread any longer.
	//All the remaining stuff is using a resident list of query IDs to form into a response
	//packet.
	ReleaseThread();

	//Now build the query response if the client has requested it.
	if(request.skipQuery == true)
		return;

	//Reset the packet buffer and data.
	wpos = 0;
	data.Clear();

	//Get the size of the response
	int sizeReq = 6;  //Query ID (4 bytes) + row count (2 bytes)
	for(size_t s = 0; s < queryRows.size(); s++)
	{
		sizeReq++;  //1 string per row
		sizeReq += PutStringReq(queryRows[s].c_str());
	}

	wpos += PutByte(&prepBuf[wpos], 1);         //_handleQueryResultMsg
	wpos += PutShort(&prepBuf[wpos], sizeReq);  //Message size

	wpos += PutInteger(&prepBuf[wpos], request.queryID);
	wpos += PutShort(&prepBuf[wpos], queryRows.size());
	for(size_t s = 0; s < queryRows.size(); s++)
	{
		wpos += PutByte(&prepBuf[wpos], 1);
		wpos += PutStringUTF(&prepBuf[wpos], queryRows[s].c_str());
		if(wpos > Global::MAX_SEND_CHUNK_SIZE)
		{
			data.Append(prepBuf, wpos);
			wpos = 0;
		}
	}
	if(wpos > 0)
		data.Append(prepBuf, wpos);

	outgoingPackets.push_back(PacketManager::PACKET_PAIR(request.socket, data));
}