A script runs on one bot's game connection, its session. session, from asterobot:bot, describes it, and a few things work differently on a Full socket bot and on a MITM bot. How bots talk to Dofus explains both modes; this page covers what they change for your code.
session
import { session } from "asterobot:bot"; Field Value What it holds gameToken string The ticket of this game connection, which IdentificationRequest sends. Keep it secret: see Keep the game ticket secret. serverId number The id of the game server the session is on. It doesn't change while the connection lasts. language string The language code the script was started with, such as fr. launchReason "initial", "resume" or "reload" Why the script started: the same value as launch.reason, described in Launch reasons. behaviorGeneration BigInt The same value as launch.generation: 1n for the first start on this game connection, one more for each start after it. connectionId BigInt Which of the bot's game connections this is: one more each time the bot gets a new one. shared boolean true on a MITM bot, where a person plays the same character. false on a Full socket bot. session is filled in when the script starts and doesn't change while it runs. It's frozen: assigning to one of its fields throws a TypeError. Each start gets a new session.
What belongs to one connection
A script started again on the same connection, after Stop then Play, finds the game where it left it: the character is already chosen and on a map, and the server won't answer a second IdentificationRequest. Only the script's own variables are gone. To carry on rather than start over, keep what it learned in the bot's memory, with the connection it belongs to:
import { memory, session } from "asterobot:bot"; import { send } from "asterobot:protocol"; const KEY = "@alice:hello/connection"; export default async function behavior(launch) { const stored = memory.get(KEY); const state = stored?.id === session.connectionId ? stored : { id: session.connectionId }; // Recorded before sending: a script stopped right after the send must never // identify a second time on this connection. A MITM bot's Dofus client has // already identified the session. if (!state.identified && !session.shared) { memory.set(KEY, { ...state, identified: true }); await send("IdentificationRequest", { ticketKey: session.gameToken, languageCode: session.language, }); } } A value stored for an earlier connection has another id, so the script knows it's out of date. Bot memory builds this into a state object that follows every step of a connection. launch.reason isn't enough to decide: when a start fails half way, the next one is still "initial" on the same connection.
Keep the game ticket secret
Caution
session.gameToken is the ticket to the bot's game session, and a stranger who has it could take that session over. Only ever put it in IdentificationRequest. Never log it, write it in a chat message, or put it in any other message.
The ticket can also show up where you don't expect it. With IdentificationRequest selected in the Network tool, Traffic shows ticketKey: the one your script sends on a Full socket bot, or the one your Dofus client sent on a MITM bot. Don't share screenshots or copies of those rows.
Full socket and MITM, for a script
The functions are the same on both kinds of bot, and a script written for one runs on the other. What differs is who else takes part:
Full socket bot MITM bot First launch.reason on a connection "initial" "resume" session.shared false true Who identifies the session Your script The Dofus client. A script's IdentificationRequest isn't sent: see Messages that aren't sent. Who answers the server's proof of identity and polls, pings, and says the character is ready on each map Your script, or @asterobot:base The Dofus client. Don't answer them too: the server would get every answer twice. Whose character send() speaks for The bot's The person playing, next to what their client sends send() with { to: "client" } Reaches your script only Reaches the Dofus client and your script Outbound messages in onTraffic() What scripts and the Network tool send Also everything the Dofus client sends What interceptors decide about Messages from the server Messages from the server and from the Dofus client When Asterobot can't keep up with the traffic It reads the connection more slowly, and no message is skipped The game goes on, and messages are skipped for scripts and the Network tool disconnect() Disconnects the bot Ends the game of the person playing On a MITM bot, Traffic in the Network tool warns when messages were skipped, with how many, saying that the bot's session discarded them because something reading the traffic couldn't keep up.
On a MITM bot, a script that would have been given a skipped message stops instead, with game traffic lost: Asterobot fell behind the game and missed messages, rather than carry on with a hole in what it saw. On either kind of bot, a script with more than 8 MB of game messages waiting for it stops with the script fell too far behind the game: see Listening.
Sharing a character
On a MITM bot (man-in-the-middle: the bot relays the game session of the Dofus client you play), the person playing and your script control the same character, and nothing coordinates them. They move, fight and open windows while your script runs, and the server receives messages from both.
A script that only watches, built from on(), wait(), onTraffic() and logging, works the same on both kinds of bot and has nothing to check. A script that acts competes with the person playing. Check session.shared to leave the controls to them: on("ChatChannelMessageEvent", async (traffic) => { // Someone is at the keyboard: let them do the talking. if (session.shared) return; // ...answer the message }); Everything the script sends goes out as their character, and other players see it. An interceptor makes the messages it decides about wait for your script, however long it takes: see Intercepting. Stopping the script doesn't touch their game: the session goes on without it. When the connection ends
A script lives on one game connection. When the connection ends, because the server closed it, the network dropped, or the person playing closed Dofus, the script first handles every message that arrived before the end, such as the server's reason for closing, then stops: its waits and requests reject, and the bot's page shows The behavior stopped with an error, with an error that starts with Game session closed:.
Nothing starts again on its own. Connect the bot again, or on a MITM bot wait for the next Dofus session, then start the script. Disconnect, delete and restart covers it from the bot's side.
disconnect()
import { disconnect } from "asterobot:bot"; disconnect(); disconnect() closes the bot's game connection. It returns right away, and calling it again does nothing. The script stops as soon as the connection is closed, so treat disconnect() as the last thing it does. The bot's page then shows The behavior stopped with an error, with behavior requested Game disconnect.
What it closes depends on the bot:
On a Full socket bot, the bot leaves the game server. It doesn't reconnect on its own. On a MITM bot, it closes both sides of the relayed session. Warning
On a MITM bot, disconnect() ends the game of the person playing: their Dofus client loses its connection to the server. Check session.shared before calling it.
This script disconnects a Full socket bot when its inventory is full, and only warns on a MITM bot:
import { session, botWarn, disconnect } from "asterobot:bot"; import { on, send } from "asterobot:protocol"; export default async function behavior(launch) { on("InventoryWeightEvent", (traffic) => { const weight = traffic.payload?.inventoryWeight; const max = traffic.payload?.weightMax; if (weight === undefined || !max || weight < max) return; // A full inventory ends this bot's session, never a player's. if (session.shared) { botWarn("Inventory full"); return; } botWarn("Inventory full, disconnecting"); disconnect(); }); // A new game connection starts with this message. MITM bots never launch // with "initial": the Dofus client has already identified their session. if (launch.reason === "initial") { await send("IdentificationRequest", { ticketKey: session.gameToken, languageCode: session.language, }); } } Next, After a game update explains what changes for scripts when Ankama patches Dofus, and the asterobot:bot reference has every signature.
- 91 vues