****************************************************************
*** There are two files here, a header file and the cpp file ***
****************************************************************




****************************
*** messageDefinitions.h ***
****************************

#ifndef MESSAGE_DEFINITIONS_H
#define MESSAGE_DEFINITIONS_H

#include "NetworkMessage.h"
#include "stringutils.h"

#define MT_ACK 1000
#define MT_CONNECTION_REQUEST 1001
#define MT_CONNECTION_REFUSE 1002
#define MT_CONNECTION_ACCEPT 1003
#define MT_CONNECTION_CLOSE 1004
#define MT_PLAYER_REGISTER_REQUEST 1005
#define MT_CHAT_MESSAGE 1006

class NM_ConnectionRequest : public NetworkMessage {
public:
	uint8 messageVersion;
	NM_ConnectionRequest() {
		header.messageType = MT_CONNECTION_REQUEST;
	}
	NM_ConnectionRequest(uint8 _messageVersion) {
		header.messageType = MT_CONNECTION_REQUEST;
		messageVersion = _messageVersion;
	}
	NetworkMessage* getInstance() { return new NM_ConnectionRequest; }
	virtual ~NM_ConnectionRequest() {
	}
	void pack(char*& data, int& length) {
		length = nm_header_size + 1 + (0 * 2) + (0 * 4);
		assert(length < 1024);
		data = new char[length];
		int pos = 0;
		memcpy(data, &header, nm_header_size); pos += nm_header_size;
		memcpy(data+pos, &messageVersion, 1); pos += 1;
	}
	void unpack(char* data, int length) {
		int pos = 0;
		memcpy(&header, data, nm_header_size); pos += nm_header_size;
		memcpy(&messageVersion, data+pos, 1); pos += 1;
	}
};

class NM_ConnectionRefuse : public NetworkMessage {
public:
	uint8 messageVersion;
	NM_ConnectionRefuse() {
		header.messageType = MT_CONNECTION_REFUSE;
	}
	NM_ConnectionRefuse(uint8 _messageVersion) {
		header.messageType = MT_CONNECTION_REFUSE;
		messageVersion = _messageVersion;
	}
	NetworkMessage* getInstance() { return new NM_ConnectionRefuse; }
	virtual ~NM_ConnectionRefuse() {
	}
	void pack(char*& data, int& length) {
		length = nm_header_size + 1 + (0 * 2) + (0 * 4);
		assert(length < 1024);
		data = new char[length];
		int pos = 0;
		memcpy(data, &header, nm_header_size); pos += nm_header_size;
		memcpy(data+pos, &messageVersion, 1); pos += 1;
	}
	void unpack(char* data, int length) {
		int pos = 0;
		memcpy(&header, data, nm_header_size); pos += nm_header_size;
		memcpy(&messageVersion, data+pos, 1); pos += 1;
	}
};

class NM_ConnectionAccept : public NetworkMessage {
public:
	NM_ConnectionAccept() {
		header.messageType = MT_CONNECTION_ACCEPT;
	}
	NetworkMessage* getInstance() { return new NM_ConnectionAccept; }
	virtual ~NM_ConnectionAccept() {
	}
	void pack(char*& data, int& length) {
		length = nm_header_size + 0 + (0 * 2) + (0 * 4);
		assert(length < 1024);
		data = new char[length];
		int pos = 0;
		memcpy(data, &header, nm_header_size); pos += nm_header_size;
	}
	void unpack(char* data, int length) {
		int pos = 0;
		memcpy(&header, data, nm_header_size); pos += nm_header_size;
	}
};

class NM_ConnectionClose : public NetworkMessage {
public:
	NM_ConnectionClose() {
		header.messageType = MT_CONNECTION_CLOSE;
	}
	NetworkMessage* getInstance() { return new NM_ConnectionClose; }
	virtual ~NM_ConnectionClose() {
	}
	void pack(char*& data, int& length) {
		length = nm_header_size + 0 + (0 * 2) + (0 * 4);
		assert(length < 1024);
		data = new char[length];
		int pos = 0;
		memcpy(data, &header, nm_header_size); pos += nm_header_size;
	}
	void unpack(char* data, int length) {
		int pos = 0;
		memcpy(&header, data, nm_header_size); pos += nm_header_size;
	}
};

class NM_PlayerRegisterRequest : public NetworkMessage {
public:
	uint16* name; uint16 length_of_name;
	NM_PlayerRegisterRequest() {
		header.messageType = MT_PLAYER_REGISTER_REQUEST;
		name = NULL;
	}
	NM_PlayerRegisterRequest(uint16* _name) {
		header.messageType = MT_PLAYER_REGISTER_REQUEST;
		name = uint16strdup(_name); length_of_name = (int)uint16strlen(name) * 2;
	}
	NetworkMessage* getInstance() { return new NM_PlayerRegisterRequest; }
	virtual ~NM_PlayerRegisterRequest() {
		if (name) free(name);
	}
	void pack(char*& data, int& length) {
		length = nm_header_size + 0 + (1 * 2) + (0 * 4) + length_of_name;
		assert(length < 1024);
		data = new char[length];
		int pos = 0;
		memcpy(data, &header, nm_header_size); pos += nm_header_size;
		memcpy(data+pos, &length_of_name, 2); pos += 2;
		memcpy(data+pos, name, length_of_name); pos += length_of_name;
	}
	void unpack(char* data, int length) {
		int pos = 0;
		memcpy(&header, data, nm_header_size); pos += nm_header_size;
		memcpy(&length_of_name, data+pos, 2); pos += 2;
		name = (uint16*)malloc(length_of_name + 2); name[length_of_name/2] = 0;
		memcpy(name, data+pos, length_of_name); pos += length_of_name;
	}
};

class NM_ChatMessage : public NetworkMessage {
public:
	uint8 flags;
	uint16* text; uint16 length_of_text;
	NM_ChatMessage() {
		header.messageType = MT_CHAT_MESSAGE;
		text = NULL;
	}
	NM_ChatMessage(uint8 _flags, uint16* _text) {
		header.messageType = MT_CHAT_MESSAGE;
		flags = _flags;
		text = uint16strdup(_text); length_of_text = (int)uint16strlen(text) * 2;
	}
	NetworkMessage* getInstance() { return new NM_ChatMessage; }
	virtual ~NM_ChatMessage() {
		if (text) free(text);
	}
	void pack(char*& data, int& length) {
		length = nm_header_size + 1 + (1 * 2) + (0 * 4) + length_of_text;
		assert(length < 1024);
		data = new char[length];
		int pos = 0;
		memcpy(data, &header, nm_header_size); pos += nm_header_size;
		memcpy(data+pos, &flags, 1); pos += 1;
		memcpy(data+pos, &length_of_text, 2); pos += 2;
		memcpy(data+pos, text, length_of_text); pos += length_of_text;
	}
	void unpack(char* data, int length) {
		int pos = 0;
		memcpy(&header, data, nm_header_size); pos += nm_header_size;
		memcpy(&flags, data+pos, 1); pos += 1;
		memcpy(&length_of_text, data+pos, 2); pos += 2;
		text = (uint16*)malloc(length_of_text + 2); text[length_of_text/2] = 0;
		memcpy(text, data+pos, length_of_text); pos += length_of_text;
	}
};

#endif






******************************
*** messageDefinitions.cpp ***
******************************

#include "pch.h"
#include "messageDefinitions.h"

void setupMessageClassMap()
{
	NetworkMessage::nm_header_size = sizeof(nm_header);
	NetworkMessage::messageClassMap[MT_CONNECTION_REQUEST] = new NM_ConnectionRequest;
	NetworkMessage::messageClassMap[MT_CONNECTION_REFUSE] = new NM_ConnectionRefuse;
	NetworkMessage::messageClassMap[MT_CONNECTION_ACCEPT] = new NM_ConnectionAccept;
	NetworkMessage::messageClassMap[MT_CONNECTION_CLOSE] = new NM_ConnectionClose;
	NetworkMessage::messageClassMap[MT_PLAYER_REGISTER_REQUEST] = new NM_PlayerRegisterRequest;
	NetworkMessage::messageClassMap[MT_CHAT_MESSAGE] = new NM_ChatMessage;
	NetworkMessage::messageNameMap[MT_CONNECTION_REQUEST] = "MT_CONNECTION_REQUEST";
	NetworkMessage::messageNameMap[MT_CONNECTION_REFUSE] = "MT_CONNECTION_REFUSE";
	NetworkMessage::messageNameMap[MT_CONNECTION_ACCEPT] = "MT_CONNECTION_ACCEPT";
	NetworkMessage::messageNameMap[MT_CONNECTION_CLOSE] = "MT_CONNECTION_CLOSE";
	NetworkMessage::messageNameMap[MT_PLAYER_REGISTER_REQUEST] = "MT_PLAYER_REGISTER_REQUEST";
	NetworkMessage::messageNameMap[MT_CHAT_MESSAGE] = "MT_CHAT_MESSAGE";
}