/* * 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; }