Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Packet Tutorial
#1
Introduction
I will explain the following:
- Sending packets from the client to server, and how to recieve them.
- Sending packets from server to client, and how to recieve them.

This is for http://www.miragesource.com use. Since Elysium Source uses Select Case for their packet system which is faster. But the packet is still the same.

Client to Server
This is how the code will look like finished (so to use it, just create a command button, and place this code in it):
Code:
Dim Packet As String
Packet = "GiveMeMyName" & SEP_CHAR & END_CHAR
Call SendData(Packet)

Now in the server, open modHandleData or search for Sub HandleData.
And just below:
Code:
' Handle Data
    Parse = Split(Data, SEP_CHAR)
Add:
Code:
' ::::::::::::::::::::::::::::::::::
    ' :: Give the player his name  ::
    ' ::::::::::::::::::::::::::::::::::
    If LCase(Parse(0)) = "GiveMeMyName" Then
            Call PlayerMsg(Index, "Your name is: " & GetPlayerName(index), 1)
        Exit Sub
    End If

So now I will explain how that actually works. In the client we had:
Dim Packet As String ' This defines the variable Packet as a "word".
Packet = "GiveMeMyName" & SEP_CHAR & END_CHAR ' Here it gives the variable the correct memory, you always need to have a name of the packet, here that is: "GiveMeMyName". I will go through SEP and END later.
Call SendData(Packet) ' Here we sends it to the server.

So now, we made a easy packet. But what if you want to send variables in the packet, then it's time to learn about SEP_CHAR and END_CHAR.
SEP_CHAR: This is the thing that divides the packet up in pieces. It let's you have different variables between them. Like this:
Code:
Packet = "GiveMeMyName" & SEP_CHAR & "2" & SEP_CHAR & GetPlayerLevel(MyIndex) & SEP_CHAR & END_CHAR
If you study that, you can see how it works, you always have a SEP_CHAR after the packet name, and always between variables, and always before END_CHAR.
END_CHAR: This is the place that tells the code were the end of the packet is. You always use it in the end of the packet, as shown above.

But how do you recieve the variables that you send to the server?
You simply do this:
Code:
' ::::::::::::::::::::::::::::::::::
    ' :: Give the player his name  ::
    ' ::::::::::::::::::::::::::::::::::
    If LCase(Parse(0)) = "GiveMeMyName" Then
        i = Val(Parse(1)) ' This will make i = 2
        n = Val(Parse(2)) ' This will make n the players Level
            Call PlayerMsg(Index, "You are level: " & n & ", your special number is: " & i & ".", 1)
        Exit Sub
    End If
That wasn't hard if you go through the code above. Just remember this, in the above example I sent two numbers in the packet (2, and the players level). If you send for example "Bob". Then you will do this to:
Name = Parse(1) ' If it now was the first variable sent in the packet.

Server to Client

Under construction...
Reply
#2
Hail _/
Reply
#3
Hehe, I wrote it for a member on my forum some time back.
Reply
#4
Hmm, well did I say anything about cases in the tutorial? well anyway..

.. didn't know that, spent like 1 hour making them into cases in Phoenix and my game K2h Tongue
Reply
#5
the sub thing only works well if you amster AddressOf and and such like the byte buffer, otherwise, its pointless because you still do the if statements.[/code]
Reply
#6
Dave Wrote:
Quote:This is for http://www.miragesource.com use. Since Elysium Source uses Select Case for their packet system which is faster. But the packet is still the same.

You did too!

Why not make every packet into a different sub, that IS faster!
Ohh hehe.. well it was some time ago I wrote it so didn't remember. But thanks for telling me that if and case has the same speed.
Reply
#7
grimsk8ter11 Wrote:the sub thing only works well if you amster AddressOf and and such like the byte buffer, otherwise, its pointless because you still do the if statements.[/code]

Actually, I dont believe it is. I have not in-depth looked into how Select Case works, but I believe it takes the argument and compairs it to multiple scenerios without calculating each one. Though since you're just using "If String(0) = 'MyString' Then", not sure - I can definately tell you any improvement would be very insignificant.

If anything, I reccomend breaking it up into select case statements and then moving them to seperate subs just for organization - makes it a hell of a lot easier to find what you need without digging through 10000 lines of one module. :wink:
Reply
#8
wouldnt work because unless yous tored the packet globally, youd ahve to pass it on.
Reply
#9
I would think select case would be slightly faster.
It always knows the thing being compared with a select case, but with a lot of ifs and elses theres more for the comp to look at. It doesnt know whats being compared till it reads the whole things, select cases know the first thing being compared.

Of course I have no idea if that makes sense to other or if its even true xD.
Reply
#10
grimsk8ter11 Wrote:wouldnt work because unless yous tored the packet globally, youd ahve to pass it on.

Not exactly - you can handle it in the same module it is in now, then just pass off the packet information as a parameter.
Reply
#11
Interesting, Dave. I will look that up. Thanks! Big Grin
Reply
#12
Ermm i Practice this in a note pad..

CLIENT::
Packet As String
Packet = "MYREALPACKET" & SEP_CHAR & "BOB" & SEP_CHAR & END CHAR
SendData(Packet)
End Sub

SERVERSIDE::
If LCase(Parse(0)) = "myrealpacket" Then
i = Val(Parse(1)) ' i equals BOB
Exit Sub
End If

Is It Right?

Edit::
another one i did,
Packet As String
Packet = "MYNAME" & SEP_CHAR & GetPlayerName(MyIndex) & SEP_CHAR & END_CHAR
SendData(Packet)

If LCase(Parse(0)) = "myname" Then
i = Val(Parse(1)) ' i equals the players name
Exit Sub
End If

I hope theyre right ^_^
Reply
#13
Nope. It won't.

Val(w/e) is used to get a numerical value from a string. This is why we use it in modHandleData, because we send packet's as strings.

If you are sending a string of data (ie. someone's name) then you do not add a 'val'. It simply stay's as 'parse(1)'.

Also, every packet you create should have this:

If UBound(Parse) (amount of SEP_CHAR's found in the packet)
Call HackingAttempt
Exit sub
end if

Otherwise your server can easily be crashed.

Yes, this was created by Shannara, but he posted it wrong. There is actually another Parse between the last SEP_CHAR and the END_CHAR which you need to take into account.

~Kite
Quote:Robin:
Why aren't maps and shit loaded up in a dynamic array?
Jacob:
the 4 people that know how are lazy
Robin:
Who are those 4 people?
Jacob:
um
you, me, and 2 others?
Reply
#14
I guess.. but what happens if its a programming error and then everyone gets kicked from the game and all hell breaks loose!!!!11

~Kite
Quote:Robin:
Why aren't maps and shit loaded up in a dynamic array?
Jacob:
the 4 people that know how are lazy
Robin:
Who are those 4 people?
Jacob:
um
you, me, and 2 others?
Reply
#15
It will be done in a few days,
Reply


Forum Jump:


Users browsing this thread: 6 Guest(s)