Aller au contenu
Afficher dans l'application

Une meilleure façon de naviguer. En savoir plus.

Asterobot

Une application plein écran sur votre écran d'accueil avec notifications push, badges et plus encore.

Pour installer cette application sur iOS et iPadOS
  1. Appuyez sur Icône de partage dans Safari
  2. Faites défiler le menu et appuyez sur Ajouter à l'écran d'accueil.
  3. Appuyez sur Ajouter dans le coin supérieur droit.
Pour installer cette application sur Android
  1. Appuyez sur le menu à trois points (⋮) dans le coin supérieur droit du navigateur.
  2. Appuyez sur Ajouter à l'écran d'accueil ou Installer l'application.
  3. Confirmez en appuyant sur Installer.

Listening

(0 notes)

A script spends most of its time waiting for the game to say something. on() and onTraffic() register functions that Asterobot calls for each message, until you remove them or the script stops. React to messages builds a first handler; this page covers everything else.

on()

const handle = on(selector, handler);

on() registers handler for every inbound message that matches selector, and returns a handle to pass to off() later. It returns right away. The handler then runs each time a matching message arrives, with the message's traffic object as its argument.

on() only receives inbound messages: what the game server sends, and what a script or the Network tool sends to the client. Messages going to the server never reach it, whatever the selector. onTraffic() receives those.

This script warns when the character's pods are nearly full:

import { session, botWarn } 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;
    // A message Asterobot couldn't decode has no payload, and an error
    // thrown in a handler stops the whole script.
    if (weight === undefined || !max) return;

    if (weight >= max * 0.9) {
      botWarn(`Pods: ${weight} / ${max}`);
    }
  });

  // 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,
    });
  }
}

inventoryWeight and weightMax are 32-bit fields, so they read as regular numbers, not as BigInt values.

Selectors

Selector Matches
A message name, such as "InventoryWeightEvent" Messages whose type is exactly that name. Case matters.
"*" Every message, including the ones without a readable name.
A function Messages for which the function returns a truthy value. It receives the traffic object.

A few rules:

  • Asterobot doesn't check the name. A misspelled name, or one your version of Asterobot doesn't have, is accepted, and the handler never runs. The editor can help: see Finding messages.
  • A name never matches a message without a readable name, since its type is empty. Use "*" or a function to receive those.
  • A function selector is called for every inbound message, so keep it quick. If it throws, the script stops with an error that includes evaluate protocol handler selector:.

A function can match on more than a name. This handler only receives guild chat:

on(
  (traffic) => traffic.type === "ChatChannelMessageEvent" && traffic.payload?.channel === "GUILD",
  (traffic) => botInfo(`[guild] ${traffic.payload?.senderName}: ${traffic.payload?.content}`),
);

onTraffic()

const handle = onTraffic(handler);

onTraffic() has no selector: its handler receives every message, in both directions. Besides what on() receives, it gets the outbound messages, the ones going to the server:

  • on a Full socket bot, what scripts send and what someone sends from the Network tool;
  • on a MITM bot (man-in-the-middle: the bot relays the game session of the Dofus client you play), also everything your Dofus client sends.

Test traffic.direction and traffic.type in the handler to keep what you need. On a MITM bot, this shows what your client does while you play:

onTraffic((traffic) => {
  if (traffic.direction === "outbound" && traffic.type !== "") {
    botDebug("Sent:", traffic.type);
  }
});

The order handlers run in

Asterobot handles one message at a time, in the order messages go through the bot. For each message:

  1. Its handlers run one after the other, in the order they were registered. on() and onTraffic() handlers share that order.
  2. The wait() calls it matches resolve.
  3. The next message is handled.

Interceptors aren't part of this order: they decide about a message before it's delivered. See Intercepting.

An async handler runs until its first await, and the next handler starts then. The rest of it continues later, while other messages are handled. Handlers don't wait for each other, so an async handler can see other messages arrive before it finishes.

Changes made while a message is being handled work this way:

  • A handler that an earlier handler removed with off() isn't called for the current message.
  • A handler registered while a message is being handled starts with the next message.

off()

off(handle);

off() removes a handler registered with on(), onTraffic() or intercept(). It returns nothing and never throws: a handle that was already removed, or anything that isn't a handle, is ignored.

A handler can remove itself. This one only reacts to the first weight update:

const handle = on("InventoryWeightEvent", (traffic) => {
  off(handle);
  botInfo("First weight update:", traffic.payload?.inventoryWeight);
});

To act on the next matching message once, wait() is often simpler: see Waiting. Settings handlers registered with onChange() are removed with offChange(), not off(): see Read settings.

Limits

  • A script can register 256 handlers with on(), onTraffic() and intercept() together. One more throws maximum behavior handlers reached, and removing one with off() frees its place. onChange() handlers have a separate limit of 256.
  • Each run of a handler's code has 250 ms. Past that, Asterobot stops the script, with JavaScript execution deadline exceeded in the error. An await ends a run: the code after it gets its own 250 ms.
  • While your code runs, arriving messages wait in a queue of 64 entries, which they share with finished sends, timers and other events. When a burst of messages fills it, the script stops with behavior event-loop queue overflow. Short handlers keep the queue moving.

Limits lists every limit, and Async and timing explains how the 250 ms are counted.

Errors

on() and onTraffic() throw right away, as ordinary exceptions, when they can't register a handler:

Error Cause
protocol.on handler must be callable The handler passed to on() isn't a function. onTraffic() says protocol.onTraffic handler must be callable.
protocol selector cannot be empty The selector is "".
protocol selector must be a semantic type, '*', or predicate The selector is neither a string nor a function.
maximum behavior handlers reached The script already has 256 handlers.

Once a handler is registered, an error that escapes it stops the whole script: a thrown error, or, in an async handler, an await that fails without a catch. The behavior stopped with an error then appears on the bot's page, with an error that includes Game traffic handler failed: for a thrown error, or unhandled Promise rejection: for a failed await.

So check the payload before reading it, and put the awaits of a handler in try/catch:

on("ChatChannelMessageEvent", async (traffic) => {
  // Only the exact command: the game also sends our own reply back to us.
  if (traffic.payload?.content !== "!ping") return;

  try {
    await send("ChatChannelMessageRequest", { channel: "GLOBAL", content: "pong" });
  } catch (error) {
    // An error that escapes a handler stops the whole script.
    botWarn("Couldn't answer:", String(error));
  }
});

When handlers stop

Handlers live as long as the script. When it stops, because you clicked Stop, an error ended it, Run restarted it or the game connection closed, all its handlers go with it. The next start registers them again, from the top of your code.

Next, Waiting covers wait(), and the asterobot:protocol reference has every signature.

Commentaires des utilisateurs

Aucun avis à afficher.

Compte

Navigation

Recherche

Recherche

Configurer les notifications push du navigateur

Chrome (Android)
  1. Appuyez sur l'icône de cadenas à côté de la barre d'adresse.
  2. Tap Autorisations → Notifications.
  3. Ajustez vos préférences.
Chrome (Desktop)
  1. Cliquez sur l'icône représentant un cadenas dans la barre d'adresse..
  2. Select Paramètres du site.
  3. Find Notifications et ajustez vos préférences.