예제 #1
0
파일: socket.cpp 프로젝트: Zaela/EQNet
void Socket::sendPacketFragmented(Packet* p)
{
	// fragment packets:
	// first chunk - proto op, seq, 32-bit length, 502 bytes of data
	// subsequent - proto op, seq, 506 bytes of data

	byte* data = p->getRawBuffer();
	uint32_t len = p->lengthWithOverhead();

	byte buf[SEND_PACKET_MAX_SIZE];
	
	uint16_t* ptr = (uint16_t*)buf;
	*ptr = toNetworkShort(OP_Fragment);

	// first chunk
	ptr[1] = toNetworkShort(getNextSequence());

	// stated len is minus all overhead except app opcode
	uint32_t minus;
	if (p->hasSequence()) // would we ever fragment a non-sequenced packet? gonna get sequenced anyway
		minus = 4; // protocol opcode + seq
	else
		minus = 2; // protocol opcode

	uint32_t* lenPtr = (uint32_t*)(buf + 4);
	*lenPtr = toNetworkLong(len - minus); 

	// copy first 502 bytes
	memcpy(buf + 8, data + minus, 502);
	uint32_t pos = minus + 502;

	// send
	sendPacket(buf, SEND_PACKET_MAX_SIZE_BEFORE_CRC);

	// subsequent chunks
	byte* bufWrite = buf + 4;

	while (pos < len)
	{
		ptr[1] = toNetworkShort(getNextSequence());

		uint32_t chunkLen = len - pos;
		if (chunkLen > 506)
			chunkLen = 506;

		memcpy(bufWrite, data + pos, chunkLen);

		sendPacket(buf, chunkLen + 4);
		pos += chunkLen;
	}
}
void ESceneSequencer::Logic()
{
   /* Si il n'y a aucune séquence en court, on prend la suivante dans la liste */
   if (_lpCurrentSequence == NULL && ESequenceContainer::g_ListSequence.getCount()>0)
   {
      // Recherche la prochaine séquence non active
      _lpCurrentSequence = getNextSequence();
      // Aucune séquence à venir, on a finit...
      if (_lpCurrentSequence == NULL) {
         return;
      } else {
         _lpCurrentSequence->getContent()->Start();
      }
   }
   /* Si la séquence courante est terminée, on la supprime de la liste et on prend la suivante dans la liste */
   if (_lpCurrentSequence) {
      bool bCompleted = false;

      bCompleted = _lpCurrentSequence->getContent()->isCompleted();
      if (bCompleted) {
         // Supprime la séquence de la liste
         ESequenceContainer::g_ListSequence.remove(_lpCurrentSequence);
         _lpCurrentSequence->DeleteContent();
         XDELETE(_lpCurrentSequence);
         
         // Recherche la prochaine séquence non active
         _lpCurrentSequence = getNextSequence();
         // Aucune séquence à venir, on a finit...
         if (_lpCurrentSequence == NULL) {
            return;
         } else {
            _lpCurrentSequence->getContent()->Start();
         }
      }
   }
   
   if (_lpCurrentSequence) {
      if (_lpCurrentSequence->getContent()->isActive()) {
         _lpCurrentSequence->getContent()->Logic();
      }
   }
}
예제 #3
0
파일: socket.cpp 프로젝트: Zaela/EQNet
void Socket::processSendQueue()
{
	uint32_t numPackets = mSendQueue.size();

	if (numPackets == 0)
		return;

	if (numPackets == 1)
	{
		processSinglePacketQueue();
		return;
	}

	CombinedPacket comb;

	for (uint32_t i = 0; i < numPackets; ++i)
	{
		Packet* p = mSendQueue[i];
		uint16_t len = p->lengthWithOverhead();

		if (len > SEND_PACKET_MAX_SIZE_BEFORE_CRC)
		{
			sendPacket(comb);
			sendPacketFragmented(p);
			continue;
		}

		if (p->hasSequence())
		{
			p->setSequence(getNextSequence());
			recordSentPacket(*p);
		}

		if (!comb.addPacket(p))
		{
			sendPacket(comb);
			sendPacket(p);
		}
	}

	sendPacket(comb);

	for (Packet* p : mSendQueue)
	{
		if (!p->isNoDelete())
			delete p;
	}

	mSendQueue.clear();
}
예제 #4
0
파일: socket.cpp 프로젝트: Zaela/EQNet
void Socket::processSinglePacketQueue()
{
	Packet* p = mSendQueue[0];

	if (p->lengthWithOverhead() > SEND_PACKET_MAX_SIZE_BEFORE_CRC)
	{
		sendPacketFragmented(p);
	}
	else
	{
		if (p->hasSequence())
		{
			p->setSequence(getNextSequence());
			recordSentPacket(*p);
		}
		sendPacket(p);
	}

	if (!p->isNoDelete())
		delete p;
	mSendQueue.clear();
}