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.

Waiting

(0 notes)

wait() pauses your code until a message you describe arrives, and hands you that message. It's the tool for "do something, then carry on when the game answers".

wait()

const traffic = await wait(selector, { timeout: 5000 });

wait() returns a promise that resolves with the traffic object of the next message matching selector. The selector is the same as for on(): a message name, "*" for any message, or a function that returns true for the message you want. Listening describes them.

The rest of the bot doesn't pause while you wait. Handlers keep running, and other parts of your code can wait for other messages at the same time.

Only inbound messages

wait() only sees inbound messages: what the game server sends, and what a script or the Network tool sends to the client. A message going to the server never resolves a wait, even with "*". Use onTraffic() to see those.

No timeout unless you pass one

Important

wait() has no timeout of its own. Without { timeout }, a wait that never matches stays open until the script stops, and the code after it never runs. Always pass a timeout.

timeout is a number of milliseconds greater than zero. When it runs out, the promise rejects with protocol wait timed out. That's what gets your code going again when a message doesn't come, whether the game never sends it or its name changed after an update.

Function Default timeout
wait() None: it waits until the script stops
send() 30 seconds
request() 30 seconds

A wait can't be cancelled. It ends when a message matches, when its timeout runs out, or when the script stops, so give it the shortest timeout that makes sense.

Start waiting before you send

A wait only sees messages that arrive after wait() was called. It doesn't look back.

That matters when you send a message and wait for the game's answer. Nothing guarantees that send() resolves before the answer arrives, so a wait started after await send() can miss an answer that came quickly. Start the wait first, and await both together:

const [echo] = await Promise.all([
  wait(
    (traffic) => traffic.type === "ChatChannelMessageEvent" && traffic.payload?.content === text,
    { timeout: 5000 },
  ),
  send("ChatChannelMessageRequest", { channel: "PARTY", content: text }),
]);

wait() is called first, so it's in place before the message goes out. Promise.all resolves with both results, the matching message first, and rejects as soon as either one fails.

Don't store the wait's promise to await it after send():

// Don't: if send() rejects, this wait is left behind.
const pending = wait("ChatChannelMessageEvent", { timeout: 5000 });
await send("ChatChannelMessageRequest", { channel: "PARTY", content: text });
await pending;

If send() rejects there, nothing awaits pending any more. Its timeout rejects it later with nothing to handle the rejection, and an unhandled rejection stops the script. Promise.all handles both promises, so a rejection that comes after the other one failed does no harm.

Several waits for one message

  • When several waits match the same message, they all resolve with it, in the order they were started.
  • Waits resolve after every on() and onTraffic() handler has run for that message.
  • A function selector that throws stops the whole script, not only the wait, with an error that includes evaluate protocol wait selector:.
  • A script can have 128 waits open at once. One more rejects with behavior resource limit exceeded: maximum waits reached.

Patterns

Carry on when nothing comes

Catch the timeout and decide what happens next:

try {
  const traffic = await wait("InventoryWeightEvent", { timeout: 10000 });
  botInfo("Pods:", traffic.payload?.inventoryWeight);
} catch (error) {
  // No update can also mean the weight didn't change.
  botWarn("No weight update:", String(error));
}

Wait for one of several messages

A function selector can accept several names, and the message you get tells you which one came:

const names = new Set(["InventoryWeightEvent", "InventoryContentEvent"]);
const traffic = await wait((candidate) => names.has(candidate.type), { timeout: 10000 });

botInfo("Received", traffic.type);

Wait inside a handler

Waiting in an async handler doesn't hold up other handlers or messages, which is how the handler gets to see the answer arrive. Put the wait in try/catch: a timeout that escapes a handler stops the script.

This script repeats in the party channel what a party member asks it to say with !say, and checks that the line went through:

import { session, botInfo, botWarn } from "asterobot:bot";
import { on, send, wait } from "asterobot:protocol";

export default async function behavior(launch) {
  on("ChatChannelMessageEvent", async (traffic) => {
    const content = traffic.payload?.content;
    if (traffic.payload?.channel !== "PARTY" || typeof content !== "string" || !content.startsWith("!say ")) return;

    const text = content.slice("!say ".length);
    // Never repeat a command: the game sends our own line back to us.
    if (text === "" || text.startsWith("!")) return;

    try {
      await Promise.all([
        wait(
          (echo) => echo.type === "ChatChannelMessageEvent" && echo.payload?.content === text,
          { timeout: 5000 },
        ),
        send("ChatChannelMessageRequest", { channel: "PARTY", content: text }),
      ]);
      botInfo("Said in party:", text);
    } catch (error) {
      // An error that escapes a handler stops the whole script.
      botWarn("Couldn't say it:", String(error));
    }
  });

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

Errors

wait() never throws: every problem rejects its promise.

Error Cause
protocol wait timed out The timeout ran out before a message matched.
behavior resource limit exceeded: maximum waits reached 128 waits are already open.
timeout/milliseconds must be a finite positive Number timeout is 0, negative, or not a number.
timeout/milliseconds is too large timeout is too large to be a duration.
protocol options must be an object The second argument isn't an object.
unknown protocol option "retries" The options have a key other than timeout and to. to is accepted and ignored.
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.

Next, Sending covers send() and request(), and Limits lists every limit.

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.