Beispiel #1
0
uint32 EQProtocolPacket::Decompress(const unsigned char *buffer, const uint32 length, unsigned char *newbuf, uint32 newbufsize)
{
    uint32 newlen=0;
    uint32 flag_offset=0;
    newbuf[0]=buffer[0];
    if (buffer[0]==0x00) {
        flag_offset=2;
        newbuf[1]=buffer[1];
    } else
        flag_offset=1;

    if (length>2 && buffer[flag_offset]==0x5a) {
        newlen=InflatePacket(buffer+flag_offset+1,length-(flag_offset+1)-2,newbuf+flag_offset,newbufsize-flag_offset)+2;
        newbuf[newlen++]=buffer[length-2];
        newbuf[newlen++]=buffer[length-1];
    } else if (length>2 && buffer[flag_offset]==0xa5) {
        memcpy(newbuf+flag_offset,buffer+flag_offset+1,length-(flag_offset+1));
        newlen=length-1;
    } else {
        memcpy(newbuf,buffer,length);
        newlen=length;
    }

    return newlen;
}
Beispiel #2
0
bool EmuTCPConnection::ProcessReceivedDataAsPackets(char* errbuf) {
	if (errbuf)
		errbuf[0] = 0;
	int32 base = 0;
	int32 size = 7;
	uchar* buffer;
	ServerPacket* pack = 0;
	while ((recvbuf_used - base) >= size) {
		EmuTCPNetPacket_Struct* tnps = (EmuTCPNetPacket_Struct*) &recvbuf[base];
		buffer = tnps->buffer;
		size = tnps->size;
		if (size >= MaxTCPReceiveBuffferSize) {
#if TCPN_DEBUG_Memory >= 1
			std::cout << "TCPConnection[" << GetID() << "]::ProcessReceivedDataAsPackets(): size[" << size << "] >= MaxTCPReceiveBuffferSize" << std::endl;
			DumpPacket(&recvbuf[base], 16);
#endif
			if (errbuf)
				snprintf(errbuf, TCPConnection_ErrorBufferSize, "EmuTCPConnection::ProcessReceivedDataAsPackets(): size >= MaxTCPReceiveBuffferSize");
			return false;
		}
		if ((recvbuf_used - base) >= size) {
			// ok, we got enough data to make this packet!
			pack = new ServerPacket;
			pack->size = size - sizeof(EmuTCPNetPacket_Struct);
			// read headers
			pack->opcode = tnps->opcode;
			if (tnps->flags.compressed) {
				pack->compressed = true;
				pack->InflatedSize = *((int32*)buffer);
				pack->size -= 4;
				buffer += 4;
			}
			if (tnps->flags.destination) {
				pack->destination = *((int32*)buffer);
				pack->size -= 4;
				buffer += 4;
			}
			// end read headers
			if (pack->size > 0) {
				if (tnps->flags.compressed) {
					// Lets decompress the packet here
					pack->compressed = false;
					pack->pBuffer = new uchar[pack->InflatedSize];
					pack->size = InflatePacket(buffer, pack->size, pack->pBuffer, pack->InflatedSize);
				}
				else {
					pack->pBuffer = new uchar[pack->size];
					memcpy(pack->pBuffer, buffer, pack->size);
				}
			}
			if (pack->opcode == 0) {
				if (pack->size) {
					#if TCPN_DEBUG >= 2
						std::cout << "Received TCP Network layer packet" << std::endl;
					#endif
					ProcessNetworkLayerPacket(pack);
				}
				#if TCPN_DEBUG >= 5
					else {
						std::cout << "Received TCP keepalive packet. (opcode=0)" << std::endl;
					}
				#endif
				// keepalive, no need to process
				safe_delete(pack);
			}
			else {
				#if TCPN_LOG_PACKETS >= 1
					if (pack && pack->opcode != 0) {
						struct in_addr	in;
						in.s_addr = GetrIP();
						CoutTimestamp(true);
						std::cout << ": Logging incoming TCP packet. OPCode: 0x" << hex << setw(4) << setfill('0') << pack->opcode << dec << ", size: " << setw(5) << setfill(' ') << pack->size << " " << inet_ntoa(in) << ":" << GetrPort() << std::endl;
						#if TCPN_LOG_PACKETS == 2
							if (pack->size >= 32)
								DumpPacket(pack->pBuffer, 32);
							else
								DumpPacket(pack);
						#endif
						#if TCPN_LOG_PACKETS >= 3
							DumpPacket(pack);
						#endif
					}
				#endif
				if (RelayServer && Server && pack->destination) {
					EmuTCPConnection* con = Server->FindConnection(pack->destination);
					if (!con) {
						#if TCPN_DEBUG >= 1
							std::cout << "Error relaying packet: con = 0" << std::endl;
						#endif
						safe_delete(pack);
					}
					else
						con->OutQueuePush(pack);
				}
				else
					OutQueuePush(pack);
			}
			base += size;
			size = 7;
		}
	}
	if (base != 0) {
		if (base >= recvbuf_used) {
			safe_delete_array(recvbuf);
		} else {
			uchar* tmpbuf = new uchar[recvbuf_size - base];
			memcpy(tmpbuf, &recvbuf[base], recvbuf_used - base);
			safe_delete_array(recvbuf);
			recvbuf = tmpbuf;
			recvbuf_used -= base;
			recvbuf_size -= base;
		}
	}
	return true;
}