Jump to content
Sanchez

[C++]Game - Client / Client - Game communication with Packets

Recommended Posts

Hi,
 
In this thread I'm going to show you how to make a game-client or client-game communication with packets, instead of using the old quest-client, client-quest communication. Lets start with the game-client, in this example I will send 1 variable to the client.
 
First start with the HEADER, open your binary source and navigate to UserInterface/Packet.h. Now you will see many headers, create a new one, but search for an empty number. I will use 57, because its not used. GC means it's used for Game -> Client packet, it's just a prefix.
 

HEADER_GC_METIN2DEV

 
6XskQ.png
 
Now add the structure for the packet, this is most important part. Structure is the "body" of the packet, it contains the HEADER as BYTE and the other optional variables. As I said I just want to send one int type to the client, so add it.
 

typedef struct command_metin2dev_packet
{
	BYTE bHeader;
	int  M2int;
} TPacketGCMetin2Dev;

 
6XyLb.png

Now navigate to UserInterface/PythonNetworkStream.cpp and add your header to the CMainPacketHeaderMap class. The first parameter of the Set is the HEADER, second is the size of the structure. We will use just static size packets in this tutorial, but the third argument can be dynamic size too.

Set(HEADER_GC_METIN2DEV, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCMetin2Dev), STATIC_SIZE_PACKET));

 
6Xzno.png

Now navigate to UserInterface/PythonNtworkStreamPhaseGame.cpp and add the function to the switch.
 

			case HEADER_GC_METIN2DEV:
				ret = RecvM2DevPacket();
				break;

The name of the function will be RecvM2DevPacket:
 
6XtF4.png
 
Now declarate the function, navigate to UserInterface/PythonNetworkStream.h and add it as public:
 

bool RecvM2DevPacket();

 
6XtN0.png
 
Now add the receiver part of the code. Recv "picks" out xy bytes from the buffer and the return type of it is false if there was no data in the buffer by that size otherwise true, which means it was successful.

xy = size of the structure
 

bool CPythonNetworkStream::RecvM2DevPacket()
{
	TPacketGCMetin2Dev Metin2DevGC;

	if (!Recv(sizeof(TPacketGCMetin2Dev), &Metin2DevGC))
	{
		Tracen("Recv Metin2DevGC Packet Error");
		return false;
	}
}

 
6XzY2.png
 
Now we are calling the BINARY_M2DEV_Test function in game.py and passing the received data.
 

PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "BINARY_M2DEV_Test", Py_BuildValue("(i)", Metin2DevGC.M2int));

 
6XA1s.png 

This was the client-side of the game-client communication, lets start the server-side:
 
First of all we need to add the header again, navigate to game/packet.h and add this:
 
6XuPu.png
 
And the structure:
 

typedef struct packet_metin2dev_packet
{
	BYTE byHeader;
	int M2int;
} TPacketGCMetin2Dev;

 
6Xz4J.png
 
Now navigate to game/char.cpp and create a function which sends the packet.
 

void CHARACTER::SendMetin2DevPacket()
{

}

 
6Xvkj.png
 
Declare it in the game/char.h:
 

		void SendMetin2DevPacket();

 
Now lets add the content of the function. Create a new instance of the structure, set the values of it and send it to the client.
 

void CHARACTER::SendMetin2DevPacket()
{
	if (!GetDesc())
	{
		return;
	}

	TPacketGCMetin2Dev Metin2DevGC;

	Metin2DevGC.byHeader = HEADER_GC_METIN2DEV;
	Metin2DevGC.M2int = GetPlayerID();

	GetDesc()->Packet(&Metin2DevGC, sizeof(TPacketGCMetin2Dev));
}

 
6XyEW.png
 

Now add the last function to game.py, this will be called by the binary:

	def BINARY_M2DEV_Test(self, M2int):
		import dbg
		dbg.LogBox(str(M2int))

 
Finally, lets check how it works:
 
6XAnB.png
 
 

 
If you have any question or suggestion, please just reply to this topic.
 
Kind Regards,
Sanchez

  • Love 71

Share this post


Link to post

Awesome.

This is the reason why I love my Sanchez  :wub:

 

It's also growing time by time yy

  • Love 2

Share this post


Link to post

2013

with customize style? if yes  can you give me name of the style.?

 

thanks

  • Love 1

Share this post


Link to post

Hi everyone,
I forgot to wrote the Client-Game communication last week, but here it is now:

 
First start again with the HEADER, the name of mine would be HEADER_CG_METIN2DEVORG. Navigate to UserInterface/Packet.h and add this:
 

HEADER_CG_METIN2DEVORG = 58,

 
a1_2014_2_22_iotbcr1y26.jpg
 
I will send the VID of the player to the server with one int variable:
 

typedef struct command_metin2dev_send_packet
{
	BYTE byHeader;
	int data;
} TPacketCGMetin2DevOrg;

 
76v2E.png
 
Now navigate to UserInterface/PythonNetworkStreamModule.cpp and add this:
 

PyObject* netCallM2DevPacket(PyObject* poSelf, PyObject* poArgs)
{
	int iData;

	if (!PyArg_ParseTuple(poArgs, "i", &iData))
	{
		return Py_BuildException();
	}
	if (iData < 0)
	{
		return Py_BuildNone();
	}

	CPythonNetworkStream& rns = CPythonNetworkStream::Instance();
	rns.SendMetin2DevOrgPacket(iData);

	return Py_BuildNone();
}

 
76vGE.png

 

Open UserInterface/PythonNetworkStream.h and search for this:

bool RecvMallOpenPacket();

Add this over that:

bool SendMetin2DevOrgPacket(int data);

Open PythonNetworkStreamPhaseGame.cpp and the fill the content of the send function:

bool CPythonNetworkStream::SendMetin2DevOrgPacket(int data)
{
	TPacketCGMetin2DevOrg M2DevPacket;
	M2DevPacket.byHeader = HEADER_CG_METIN2DEVORG;
	M2DevPacket.data = data;

	if (!Send(sizeof(M2DevPacket), &M2DevPacket))
		return false;

	return SendSequence();
}

Now add the latest codes on the client side, navigate to UserInterface/PythonNetworkStreamModule.cpp and add this:
 

		// M2DEV
		{ "SendM2DevPacket", netCallM2DevPacket, METH_VARARGS },

 
a1_2014_2_22_gdld6x77xv.jpg
 
Lets continue with the server-side, first start again with the HEADER in game/packet.h:
 

HEADER_CG_METIN2DEVORG		 = 58,

 
 a1_2014_2_22_iotbcr1y26.jpg
 
And with the structure:
 

typedef struct command_metin2dev_send_packet
{
	BYTE byHeader;
	int data;
} TPacketCGMetin2DevOrg;

 
a1_2014_2_22_dug81rariy.jpg

 

The first argument of Set is HEADER, second is the size of  the structure, third is an optional string and the fourth is a boolean. Nearly the most important part of the function is the boolean, we can decide here, do we want to use sequence check? In this case I want, so set it to true.

 

Open game/packet_info.cpp and add this to the CPacketInfoCG::CPacketInfoCG():

Set(HEADER_CG_METIN2DEVORG, sizeof(TPacketCGMetin2DevOrg), "Metin2Dev", true);

Now navigate to game/input_main.cpp and add this to the switch at the end of the file:
 

		case HEADER_CG_METIN2DEVORG:
			Metin2DevReceivePacket(ch, c_pData);
			break;

 
a1_2014_2_22_jtee1wzqnd.jpg
 
Create the function for the Metin2DevReceivePacket still in game/input_main.cpp:
 

void CInputMain::Metin2DevReceivePacket(LPCHARACTER ch, const char* c_pData)
{

}

 
a1_2014_2_22_2ax2vvzpe1.jpg

Now add declaration of the Metin2DevReceivePacket to the CInputMain class in game/input.h:
 

void		Metin2DevReceivePacket(LPCHARACTER ch, const char* c_pData);

 
a1_2014_2_22_ggrf8i61jo.jpg
 
Fill the content of the function:
 

	TPacketCGMetin2DevOrg* p = (TPacketCGMetin2DevOrg*)c_pData;
	sys_log(0, "PLAYER ID: %i", p->data);

 
a1_2014_2_23_3qx2xybmxp.jpg
 
 
Thats all, now just make a simple button in the game to call this function:
 

net.SendM2DevPacket(player.GetTargetVID())

 
Example:
 

	def Button1_Event(self):
		net.SendM2DevPacket(player.GetTargetVID())

 
Finally, check how it works:
 a1_2014_2_23_bk2go8v4ml.jpg

Kind Regards,
Sanchez

  • Love 25

Share this post


Link to post

i add all in game, client src and game.py
 


	def BINARY_M2DEV_Test(self, M2int):
		import dbg
		dbg.TraceError(str(M2int))
	
	def BINARY_GuildWar_OnRecvPoint(self, gainGuildID, opponentGuildID, point):
		self.interface.OnRecvGuildWarPoint(gainGuildID, opponentGuildID, point)	

and he write not in syserr

Share this post


Link to post

is there any difs for communicate client and game in 34k files ?

 

well its not impossible to make, but this will be just stupid why work on 34k with shity and limited difs while you can do (almost anything) with src as long as you are a pro in c++

  • Love 1

Share this post


Link to post

 

is there any difs for communicate client and game in 34k files ?

 

well its not impossible to make but this will just stupid why work on 34k with shity and limited difs while you can do (almost anything) with src as long as you are a pro in c++

 

 

You are really right but i don't interesting about source of metin2 i just need communicate client and game of file for securing my hackshield, i am only developing security softwares for metin2.

 

Share this post


Link to post

 

 

is there any difs for communicate client and game in 34k files ?

 

well its not impossible to make but this will just stupid why work on 34k with shity and limited difs while you can do (almost anything) with src as long as you are a pro in c++

 

 

You are really right but i don't interesting about source of metin2 i just need communicate client and game of file for securing my hackshield, i am only developing security softwares for metin2.

 

 

interesting.. hackshield have to do server communication ?

 

communication dif file don't done with dissamble,  and communication nothing to do with dif

 

 

Share this post


Link to post

 

 

 

is there any difs for communicate client and game in 34k files ?

 

well its not impossible to make but this will just stupid why work on 34k with shity and limited difs while you can do (almost anything) with src as long as you are a pro in c++

 

 

You are really right but i don't interesting about source of metin2 i just need communicate client and game of file for securing my hackshield, i am only developing security softwares for metin2.

 

 

interesting.. hackshield have to do server communication ?

 

communication dif file don't done with dissamble,  and communication nothing to do with dif

 

 

yes but it is useless for PServer (at least right now)

packet are still on both client bin and game on server so it is possible with a dif but way harder so he will buy it for sure

Share this post


Link to post

i addet in game / client not work in game,py

def BINARY_M2DEV_Test(self, M2int):
    import dbg
    dbg.LogBox(str(M2int))

no error

Share this post


Link to post

i wrote every thin like you ..... the game is working but the logbox never shows and there is no errors

Share this post


Link to post

If I want to use more than 255 headers, I can?

Please, someone can create a tutorial? I known that i have to change the datype of header in another like int, but there are many things to change and I don't have much experience in programming.

Share this post


Link to post
PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "BINARY_M2DEV_Test", Py_BuildValue("(i)", Metin2DevGC.M2int));

How can i put a variable in instancebaseeffect with Metin2DevGC.M2int???

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • 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.