Skip to content

[How To] Intercept, Modify, Block, and Send Packets

Joseph Bingham edited this page Aug 21, 2020 · 3 revisions

Intercept, Modify, Block, and Send Packets

The packet parser is not only the backbone of TibiaAPI, but also makes it a powerful tool because you can work with packets directly. You can intercept packets, as they are parsed, to look at the data in them. You can modify* packets before they reach their destination, and even block* packets completely. You can also craft packets and send them to the server/client with ease.

* Modification and blocking of packets is only 100% reliable if the structure of that packet is known. You'll find more details about this throughout the article.

Intercept

You can easily intercept packets by subscribing to the event for that packet. For example, we can intercept the packet that contains current data for our character (health, mana, etc.):

// Create a `Client` object, and start the proxy.
using var client = new OXGaming.TibiaAPI.Client();
client.StartConnection();

// () => {}; is just syntactic-sugar so you don't have to create a separate function.
client.Connection.OnReceivedServerPlayerDataCurrentPacket += (packet) =>
{
    // Because `packet` is a base object, it needs to be casted to the right packet type.
    var data = (OXGaming.TibiaAPI.Network.ServerPackets.PlayerDataCurrent)packet;
    // Returning true tells the parser we want to forward this packet to its destination (in this case, the client).
    return true;
};

While intercepting packets isn't necessarily useful on its own (other than being able to know something before the client does; such as your player's health), it is the base for modifying and blocking packets.

Modify

We can easily modify packets by intercepting them then overriding public variables. Both server and client packets can be modified, but we'll use the server packet example above; in which case we'll need to enable server packet modification first:

client.Connection.IsServerPacketModificationEnabled = true;

Next, we can make the client think we have a higher level than we really do:

data.Level = 1000;

The parser will do the rest and overwrite the original packet with our changes before forwarding it to its desination (the client). Now when you look at the Skills window in your client you will see your level is 1000. Changing your level may not be exciting, but you can use packet modification to do more fun stuff like changing your outfit. I should note that modifications you make to server packets is only visible to you; other players won't see your level or outfit change.

If a packet doesn't have a completed AppendToNetworkMessage() function, then modifications on that packet are useless. Also, because NetworkMessages from the server can have more than one packet in it, if even one of those packets doesn't have a completed ParseFromNetworkMessage then your modifications may not uphold.

Block

Blocking a packet is done simply by intercepting the packet then returning false on the function. Both server and client packets can be blocked, but it's not really useful on server packets. So, for this example, we'll intercept the Talk client packet and block it if it starts with a specific character:

// First, enable client packet modification:
client.Connection.IsServerPacketModificationEnabled = true;

// Next, intercept the `Talk` client packet:
client.Connection.OnReceivedClientTalkPacket += (packet) =>
{
    // Cast the base packet to the one we intercepted:
    var data = (OXGaming.TibiaAPI.Network.ClientPackets.Talk)packet;
    // Check for the special character.
    if (data.Text.StartsWith("/"))
    {
        // Tell the parser to block this packet from going to its destination (server).
        return false;
    }
    // All other messages will get forward properly.
    return true;
};

Like with modifying packets, blocking packets can be inconsistent if the parser encounters packets that don't have their ParseFromNetworkMessage() and AppendToNetworkMessage() functions completed. However, unlike server NetworkMessages, client NetworkMessages will only every contain one packet; therefore, less likely to be an issue.

Send

Sending packets with TibiaAPI is really easy. All you have to do is create the packet, set the variable(s), and send it to the proper destination. For this example, we'll use a mana potion on our character:

var manaSelf = new OXGaming.TibiaAPI.Network.ClientPackets.UseOnCreature(client)
{
    CreatureId = client.Player.Id,
    ObjectId = 268, // mana potion
    Position = new OXGaming.TibiaAPI.Utilities.Position(0xFFFF, 0, 0) // hotkey
};
client.Connection.SendToServer(manaSelf);

The API takes care of everything else; turning the packet into a NetworkMessage, encrypting it, setting the correct sequence number, and sending it to the server.

Altogether Now

Let's take everything we've learned and create an auto-haste feature that we can enable/disable with chat commands.

// First, we'll need to create our `Client` object and a boolean flag to determine if our auto-haste feature is enabled:
var isAutoHasteEnabled = false;
using var client = new OXGaming.TibiaAPI.Client();

// Enable client packet modification so we can block `Text` client packets with our command identifier.
client.Connection.IsClientPacketModificationEnabled = true;

// Now let's create the `Talk` client packet we'll use to cast the haste spell:
var hasteSpell = new OXGaming.TibiaAPI.Network.ClientPackets.Talk(client)
{
    MessageMode = OXGaming.TibiaAPI.Constants.MessageMode.Say,
    Text = "utani hur"
};

// Next, we need to intercept the `Talk` client packet so we can check for our commands:
client.Connection.OnReceivedClientTalkPacket += (packet) =>
{
    var data = (OXGaming.TibiaAPI.Network.ClientPackets.Talk)packet;
    if (data.Text.StartsWith("/")
    {
        if (data.Text == "/on")
        {
            isAutoHasteEnabled = true;
        }
        else if (data.Text == "/off")
        {
            isAutoHasteEnabled = false;
        }
        return false; // block any packet that starts with our command identifier in case of typos
    }
    return true; // all other messages can be forwarded as normal
};

// Then, we need to intercept the `PlayerState` server packet to check if we need to cast our haste spell:
client.Connection.OnReceivedServerPlayerStatePacket += (packet) =>
{
    var data = (OXGaming.TibiaAPI.Network.ServerPackets.PlayerState)packet;
    // The 7th bit of the `State` integer is the haste flag; if it's not set then the player isn't hasted.
    if (isAutoHasteEnabled && (data.State & 64) == 0)
    {
        // By sending our haste spell to the server here, it theoretically could get there before the client receives this packet.
        client.Connection.SendToServer(hasteSpell);
    }
    return true;
};

// Finally, we need to start the proxy:
client.StartConnection();

Now all you need to do is login to your preferred server and send /on, in any channel, to enable your auto-haste feature, and /off, in any channel, to disable it. If you need help connecting your client to the proxy, follow this guide.

It is not recommended to use the above code on official servers as it emulates a bot feature and could get your account/character banned or deleted.