Jump to content

JSON Packets


Recommended Posts

  • Honorable Member

M2 Download Center

This is the hidden content, please
( Internal )

If you wanna bring some serialization to the networking, send floating point numbers safely between the server and the client or just don't want to define packet structures for everything this will be useful for you.

We will use rapidjson library for parsing and creating json strings but don't worry I created some helper functions to make it easier.

 

So let's start first on the server side!

Add JsonPacket.cpp and h to your game project and put the content of the include folder to you include directory.

 

Open up input.h and add the following to CInputProcessor base class:

int RecvJsonPacket(LPDESC desc, const char* data, size_t uiBytes);

 

Now go to input.cpp and add the definition:

int CInputProcessor::RecvJsonPacket(LPDESC desc, const char* data, size_t uiBytes)
{
	if (nullptr == desc || uiBytes < sizeof(TPacketJson))
	{
		return -1;
	}

	const TPacketJson* packet = (const TPacketJson*)data;

	if (uiBytes < sizeof(TPacketJson) + packet->length
		|| uiBytes > (1 << 12))
	{
		return -1;
	}

	Json::Document json;
	json.Parse<rapidjson::kParseStopWhenDoneFlag>(data + sizeof(TPacketJson));

	switch (json.GetParseError())
	{
		case rapidjson::kParseErrorNone:
		case rapidjson::kParseErrorDocumentEmpty:
			break;

		default:
			sys_err("Json Parse Error (code %d)", (int)json.GetParseError());
			return -1;
	}

	if (!JsonPacket::Recv(desc, (JsonPacket::Type)packet->type, json))
	{
		return -1;
	}

	return packet->length;
}

Don't forget to include JsonPacket.h and json.h!

 

Now go to input_main.cpp and find the function CInputMain::Analyze. Add this case:

case HEADER_CG_JSON:
    if ((iExtraLen = RecvJsonPacket(d, c_pData, m_iBufferLeft)) < 0)
    {
		return -1;
    }
    break;

 

Go to packet.h and add this structure:

struct TPacketJson
{
	uint8_t		header;
	int32_t		type;
	uint32_t	length;
};

 

Add them to the packet header enumerations:

HEADER_CG_JSON					= 170,
HEADER_GC_JSON					= 170,

 

Go to packet_info.cpp and add by the others add the following in constructor of CPatcketInfoCG.

Set(HEADER_CG_JSON, sizeof(TPacketJson), "Json Packet", true);

 

Finally add JsonPacket.cpp to you Makefile too.

 

Now let's get to the client side!

Add JsonPacket.cpp and h to your UserInterface project and the content of the include folder to your include directory.

 

Go to PythonNetworkStream.h and add the following to CPythonNetworkStream class:

bool RecvJsonPacket();

 

Now to go to PythonNetworkStream.cpp and add the definition:

bool CPythonNetworkStream::RecvJsonPacket()
{
	TPacketJson packet;
	if (!Recv(sizeof(TPacketJson), &packet))
	{
		return false;
	}

	std::vector<char> buffer(packet.length);
	if (!Recv(packet.length, buffer.data()))
	{
		return false;
	}

	Json::Document json;
	json.ParseInsitu<rapidjson::kParseStopWhenDoneFlag>(buffer.data());
	
	switch (json.GetParseError())
	{
		case rapidjson::kParseErrorNone:
		case rapidjson::kParseErrorDocumentEmpty:
			break;

		default:
			return false;
	}

	return JsonPacket::Recv((JsonPacket::Type)packet.type, json);
}

Don't forget to include JsonPacket.h and json.h!

 

Go to PythonNetworkStreamPhaseGame.cpp and add the following case in the CPythonNetworkStream::GamePhase function:

case HEADER_GC_JSON:
	ret = RecvJsonPacket();
	return;

 

Go to Packet.h and add the struct:

struct TPacketJson
{
	uint8_t		header;
	int32_t		type;
	uint32_t	length;
};

 

Add these to the packet header enumerations:

HEADER_CG_JSON								= 170,
HEADER_GC_JSON								= 170,

 

Go to PythonNetworkStream.cpp again and add this to the CMainPacketHeaderMap constructor:

Set(HEADER_GC_JSON, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketJson), DYNAMIC_SIZE_PACKET));

 

 

If you would like to send a packet, just add a new packet type to the enum and here's a sample code,  it works the exact same way on server and client side:

#include "JsonPacket.h"
  
void SomeFunction()
{
      Json::Document testPacket = Json::CreateJsonObject();
      Json::SetValue(testPacket, "fieldName1", "string value");
      Json::SetValue(testPacket, "fieldName2", 123);
      Json::SetValue(testPacket, "fieldName3", true);
      JsonPacket::Send(JsonPacket::Type::PACKET_TYPE_TEST, testPacket);
}

 

And here's the download link for the files: https://distraught.hu/download/m2dev/json-packets.zip

 

Hope you like it! ;) Good luck! :P

  • Metin2 Dev 32
  • Dislove 1
  • Good 7
  • Love 26

WRnRW3H.gif

Link to comment
Share on other sites

  • Former Staff

Pretty interesting way to manage packets here, it reminds me the way minecraft does it, could definitly see an usage in dynamic packets at least. Thanks for the release.

  • Love 1

Everyday you wake up as a Metin2 developer is a bad day...

METIN1 src when

Link to comment
Share on other sites

  • 2 years later...

Announcements



×
×
  • Create New...

Important Information

Terms of Use / Privacy Policy / Guidelines / We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.