[How/To] SMSG_MESSAGECHAT WorldPacket Server <-> Client Communication

Sylian

Trusted
Trusted
Sylian Rep
2
0
0
Rep
10
Sylian Vouches
0
0
0
Vouches
0
Posts
86
Likes
199
Bits
2 YEARS
2 YEARS OF SERVICE
LEVEL 28 56 XP
So, after taking a break from WoW Emulation, I got the itch to return to WoW Emulation. I quit because I could not figure out how to send a WorldPacket.

Last night, I spent a few hours trying to understand how the specific WorldPacket "SMSG_MESSAGECHAT" worked. I figured it out, so now I want to share it with all of you, since I don't see anyone else talking about it.
Most people would ask why we want to learn about this specific WorldPacket.
We want to learn how to utilize this WorldPacket because we can communicate Server <-> Client. This way, we send a chat message from the server to the client, which might not sound important at all, but by doing this, we can send data from the server to the client.


Example


We made a module for our server that increases a random attribute for each kill the player gets. We also created an add-on to show the increases and maybe the number of kills the player has done.
Now, we are stuck because we need to somehow transfer the data from the module to the player add-on, and this is where the WorldPacket comes into play!





Breaking Down The Packet


Now that we have built an example, we can start breaking down the packet to understand it and rebuild it in our module.

Let's first see how the WorldPacket looks when the client receives it from the server.
1724580059361.png

This looks scary, but it's much easier to understand when you break it down, so let's do that!

Here is the packet breakdown and what each byte(s) means. Remember to build the packet correctly; your client won't accept it if not.


01 = The channel the message should be sent to, "01" is the /say channel.
07 00 00 00 = The language the message was sent as, "07" is LANG_COMMON.
02 00 00 00 00 00 00 00 = The characters GUID that we want our message to be sent to, in this case, my characters GUID is "02"
00 00 00 00 = These empty bytes are what is called a "Null Terminator," these are important because, as I said before, we NEED to build the packet correctly
02 00 00 00 00 00 00 00 = The characters GUID again, I honestly don't understand why it wants the GUID again.
08 00 00 00 = The message length + 1.
45 6D 75 64 65 76 73 00 = The message we want to send; these bytes mean just "Emudevs," but depending on the message you send, they will be a longer or smaller array of bytes.
00 = This is a single byte we again NEED to add to the end of the packet.



Now that we understand how the packet sent works, we can recreate it inside our module using C++. So, let's go ahead and recreate it.


Recreating Our Packet In C++


We want to recreate and send the packet in our module, but we must ensure it is sent to the correct player.
So, for our example, we want to override the function called when the player kills another creature, so let's do that first.

C++:
    void OnCreatureKill(Player* p, Creature* c) override
    {
        if (!p)
            return;

        // Stores the players GUID for the packet.
        uint64 guid = p->GetGUID().GetRawValue();

        // Prefix for our addon.
        std::string addonPrefix = "StatIncreaser:";

        // Data we want to send with it, for this tutorial I will just make it send the characters name with it.
        std::string addonData = p->GetName();

        // The world packet we want to send, so that is SMSG_MESSAGECHAT.
        WorldPacket data(SMSG_MESSAGECHAT, 200);

        // ---->>> PLEASE NOTE: You DO NOT send accounts or sensitive data using CHAT_MSG_SAY! You would do CHAT_MSG_WHISPER instead of the CHAT_MSG_SAY!!
        // The first byte of the packet was the chat channel to which we wanted to send the message, CHAT_MSG_SAY.
        data << (uint8)CHAT_MSG_SAY;

        // ---->>>> PLEASE NOTE: You normally send data using the LANG_ADDON, but since this is a showcase, I will send it via the LANG_COMMON to show it works!!
        // We want to understand the message coming into the player so that we will send the packet as LANG_COMMON.
        data << (uint32)LANG_COMMON;

        // Now we add the GUID of our character to the packet.
        data << guid;

        // Null terminator
        data << '\0';

        // Adding the GUID for a second time.
        data << guid;

        // Now, we add the addonPrefix and addonData length together and + 1; this is the message size.
        uint32 messageSize = addonPrefix.length() + addonData.length() + 1;

        // Add the messageSize to the packet.
        data << messageSize;

        // Adds the addonPrefix and addonData text to the packet.
        data << addonPrefix + addonData;

        // Now that we are at the end of the packet, we add the last "00" to close the packet correctly.
        data << (byte)0;

        // Last thing we do is send the world packet to the player who got a kill.
        p->SendDirectMessage(&data);

        LOG_ERROR("sql.sql", "Sending addon message ->    " + addonPrefix + addonData);
    }

After all this has been setup, we will go ahead and build/compile our module again and start the server.
If everything is correct, our player would say, "StatIncrease:[CharacterName]" after each kill.
As you can see, it works perfectly!
1724597447649.png



I hope this guide/tutorial helped some of you work with world packets!

Credits:
@Jens -> Explained some of the details behind World Packets!
 
Last edited:
Liked By 4 members :

splicho

Emudevs Founder
Administrator
splicho Rep
6
0
0
Rep
6
splicho Vouches
3
0
0
Vouches
3
Posts
997
Likes
1,421
Bits
2 YEARS
2 YEARS OF SERVICE
LEVEL 248 85 XP
Dope tutorial, even though I don't understand a single line due to Skill Issues.
 
Liked By 1 member :

Azayaka

Allelujah
Administrator
Azayaka Rep
3
0
0
Rep
9
Azayaka Vouches
0
0
0
Vouches
0
Posts
321
Likes
219
2 YEARS
2 YEARS OF SERVICE
LEVEL 99 60 XP
Can't wait to see this on other forums lol!

Great post
 
Liked By 1 member :

Sylian

Trusted
Trusted
Sylian Rep
2
0
0
Rep
10
Sylian Vouches
0
0
0
Vouches
0
Posts
86
Likes
199
Bits
2 YEARS
2 YEARS OF SERVICE
LEVEL 28 56 XP
Can't wait to see this on other forums lol!

Great post
Thanks, brother.
Yeah, that's the worst about writing forum posts; others steal them without credit to the person who wrote it :PepeHands:
 

NarcoRP

El Diablo Nunca Duerme
Divine
NarcoRP Rep
1
0
0
Rep
3
NarcoRP Vouches
0
0
0
Vouches
0
Posts
132
Likes
109
2 YEARS
2 YEARS OF SERVICE
LEVEL 8 81 XP
Good contribution my friend, keep discovering things within wow that you can do
 
Liked By 1 member :

3,384

1,263

9,547

422

Top