Exemplo n.º 1
0
/*
 * Reads a string
 * Its important that the maxStringLength parameter has the same value as the maxStringLength parameter of xptPacketbuffer_writeData() that was used to write the string
 */
void xptPacketbuffer_readString(xptPacketbuffer_t* pb, char* stringData, uint32_t maxStringLength, bool* error) {
	if (maxStringLength == 0 || maxStringLength > 0xFFFF) {
		fprintf(stderr, "xptPacketbuffer_readString(): Invalid maxStringLength\n");
		// strings of max length 0 or longer than 2^16-1 are not supported
		*error = true;
		return;
	}
	maxStringLength--; // -1 since we count in the '\0' at the end
	// get size of the string + length prefix
	uint32_t stringLength = 0;
	if (maxStringLength <= 0xFF) {
		stringLength = (uint32_t)xptPacketbuffer_readU8(pb, error);
		if (*error) return;
	} else {
		stringLength = (uint32_t)xptPacketbuffer_readU16(pb, error);
		if (*error) return;
	}
	// string length valid?
	if (stringLength >= maxStringLength) {
		fprintf(stderr, "xptPacketbuffer_readString(): Stringlength invalid\n");
		*error = true;return;	
	}
	// packet data large enough?
	if ((pb->parserIndex+stringLength) > pb->bufferSize) {
		fprintf(stderr, "xptPacketbuffer_readString(): End of data in string\n");
		*error = true;return;
	}
	// write string data
	memcpy(stringData, (pb->buffer+pb->parserIndex), stringLength);
	stringData[stringLength] = '\0';
	pb->parserIndex += stringLength;
	*error = false;
}
/*
 * Called when a packet with the opcode XPT_OPC_S_MESSAGE is received
 */
bool xptClient_processPacket_message(xptClient_t* xptClient)
{
	xptPacketbuffer_t* cpb = xptClient->recvBuffer;
	// read data from the packet
	xptPacketbuffer_beginReadPacket(cpb);
	// start parsing
	bool readError = false;
	// read type field (not used yet)
	uint32 messageType = xptPacketbuffer_readU8(cpb, &readError);
	if( readError )
		return false;
	// read message text (up to 1024 bytes)
	char messageText[1024];
	xptPacketbuffer_readString(cpb, messageText, 1024, &readError);
	messageText[1023] = '\0';
	if( readError )
		return false;
	printf("Server message: %s\n", messageText);
	return true;
}
/*
 * Called when a packet with the opcode XPT_OPC_S_AUTH_ACK is received
 */
bool xptClient_processPacket_authResponse(xptClient_t* xptClient)
{
	xptPacketbuffer_t* cpb = xptClient->recvBuffer;
	// read data from the packet
	xptPacketbuffer_beginReadPacket(cpb);
	// start parsing
	bool readError = false;
	// read error code field
	uint32 authErrorCode = xptPacketbuffer_readU32(cpb, &readError);
	if( readError )
		return false;
	// read reject reason / motd
	char rejectReason[512];
	xptPacketbuffer_readString(cpb, rejectReason, 512, &readError);
	rejectReason[511] = '\0';
	if( readError )
		return false;
	if( authErrorCode == 0 )
	{
		xptClient->clientState = XPT_CLIENT_STATE_LOGGED_IN;
		printf("xpt: Logged in with %s\n", xptClient->username);
		if( rejectReason[0] != '\0' )
			printf("Message from server: %s\n", rejectReason);
		// start ping mechanism
		xptClient->time_sendPing = (uint32)time(NULL) + 60; // first ping after one minute
	}
	else
	{
		// error logging in -> disconnect
		printf("xpt: Failed to log in with %s\n", xptClient->username);
		if( rejectReason[0] != '\0' )
			printf("Reason: %s\n", rejectReason);
		return false;
	}
	// get algorithm used by this worker
	xptClient->algorithm = xptPacketbuffer_readU8(cpb, &readError);
	return true;
}