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.

Protocole Dofus

Le protocole Dofus actuellement pris en charge par Asterobot
Turns on or off the notification shown when a mutual contact logs in.
Kind request · Area Game.Social
One of the social "warn me when..." toggles the client mirrors to the server. THE SERVER HAS TO BE TOLD because it is the side that decides whether to push the notification; the client cannot honour the setting locally.
IT IS SENT IMMEDIATELY ON EVERY FLIP, WITH NO DEBOUNCE. The option lives in Options -> General, in the Social block. Flipping it publishes a one-boolean event that a writer turns straight into this message. A script that toggles this in a loop produces a burst of requests that no human interaction could.
SEND IT ONLY WHEN THE SETTING ACTUALLY CHANGES. It is a persisted client option replayed verbatim, not a query and not a subscription.
When you may send it
Requires character_loaded observed Raised by: the player flips the toggle in Options -> General, Social block proven Related messages
Nothing answers it - send it and move on it mirrors a stored client option to the server; no dumped build has a matching acknowledgement message Fields
#FieldTypeMeaningYou set it 1enableboolTrue to be notified when a mutual contact comes online; false to suppress it.
The persisted client option, replayed verbatim.required
  • summary: Turns on or off the notification shown when a mutual contact logs in.
  • area: Game.Social
  • 62 vues
Turns on or off the notification shown when a friend, guild member or nearby character gains a level.
Kind request · Area Game.Social
One of the social "warn me when..." toggles the client mirrors to the server. THE SERVER HAS TO BE TOLD because it is the side that decides whether to push the notification; the client cannot honour the setting locally.
IT IS SENT IMMEDIATELY ON EVERY FLIP, WITH NO DEBOUNCE. The option lives in Options -> General, in the Social block. Flipping it publishes a one-boolean event that a writer turns straight into this message. A script that toggles this in a loop produces a burst of requests that no human interaction could.
SEND IT ONLY WHEN THE SETTING ACTUALLY CHANGES. It is a persisted client option replayed verbatim, not a query and not a subscription.
When you may send it
Requires character_loaded observed Raised by: the player flips the toggle in Options -> General, Social block proven Related messages
Nothing answers it - send it and move on it mirrors a stored client option to the server; no dumped build has a matching acknowledgement message Fields
#FieldTypeMeaningYou set it 1enableboolTrue to be notified when a friend, guild member or character on the current map levels up; false to suppress it.
The persisted client option, replayed verbatim.required
  • summary: Turns on or off the notification shown when a friend, guild member or nearby character gains a level.
  • area: Game.Social
  • 59 vues
Asks for one section of the player's guild data - general, members, boosts, houses, recruitment or logbook.
Kind request · Area Game.Guild
THE GUILD WINDOW DOES NOT GET EVERYTHING AT ONCE. Each tab asks for the section it needs and the server answers with the matching event. This request carries nothing but the section selector, so it is a pure "give me X".
ASK FOR THE SECTION YOU ACTUALLY WANT. The sections are separate round trips; asking for all six because you might need one is traffic the real client does not produce - it asks on tab navigation.
information_type IS RENUMBERED RELATIVE TO THE REFERENCE BUILD AND THIS IS THE TRAP. See InformationType: three of the six values moved, so code carried across from an older schema asks for the wrong section without any error.
The client also sends this once at world entry, as the last of the four-request burst that follows ContextCreationRequest - see FriendListRequest for the whole burst.
When you may send it
Requires character_loaded observed Raised by: the player opens the guild window or switches one of its tabs proven Related messages
Reply not yet recovered: each section is answered by its own event - general information, member list, boosts, houses, recruitment settings, logbook. None of those has a signature here yet, so match them by arrival. Sequence
Step post_character_load.4 observed — of 4 requests; a capture shows it three milliseconds after the first three
Fields
#FieldTypeMeaningYou set it 2information_typeInformationTypeWhich section of the guild data is wanted.
An InformationType value.
RENUMBERED since the reference build - read the enum page before hardcoding a number.required
  • summary: Asks for one section of the player's guild data - general, members, boosts, houses, recruitment or logbook.
  • area: Game.Guild
  • 70 vues
Asks the server to start notifying this character when a guild member comes online. Empty payload.
Kind request · Area Game.Guild
The subscribe half of a mutually exclusive pair with GuildMemberWarnOnConnectionStopRequest. Both carry nothing; WHICH MESSAGE YOU SEND IS THE ENTIRE PAYLOAD.
THE SERVER HOLDS THE SUBSCRIPTION STATE, NOT YOU. The client keeps its own copy of the checkbox as a persisted option, but that copy is a UI convenience and IS NEVER REPLAYED TO THE SERVER - it is not sent at login and not sent on reconnect. So the server's idea of your subscription survives your client restarting, and sending nothing means "leave it as it was".
Send one of the pair only when the setting actually changes.
When you may send it
Requires character_loaded observed Raised by: the player ticks or unticks the guild-member connection warning in the guild members panel proven Related messages
Nothing answers it - send it and move on the server holds the subscription; no dumped build has an acknowledgement message for it No fields you may set.
  • summary: Asks the server to start notifying this character when a guild member comes online. Empty payload.
  • area: Game.Guild
  • 65 vues
Asks the server to stop notifying this character when a guild member comes online. Empty payload.
Kind request · Area Game.Guild
The unsubscribe half of a mutually exclusive pair with GuildMemberWarnOnConnectionStartRequest. Both carry nothing; WHICH MESSAGE YOU SEND IS THE ENTIRE PAYLOAD.
THE SERVER HOLDS THE SUBSCRIPTION STATE, NOT YOU. The client keeps its own copy of the checkbox as a persisted option, but that copy is a UI convenience and IS NEVER REPLAYED TO THE SERVER - it is not sent at login and not sent on reconnect. So the server's idea of your subscription survives your client restarting, and sending nothing means "leave it as it was".
Send one of the pair only when the setting actually changes.
When you may send it
Requires character_loaded observed Raised by: the player ticks or unticks the guild-member connection warning in the guild members panel proven Related messages
Nothing answers it - send it and move on the server holds the subscription; no dumped build has an acknowledgement message for it No fields you may set.
  • summary: Asks the server to stop notifying this character when a guild member comes online. Empty payload.
  • area: Game.Guild
  • 61 vues
Asks when the guild's current mission week ends. Empty payload.
Kind request · Area Game.Guild
Guild missions run on a weekly cycle and THE CLIENT DOES NOT COMPUTE THE BOUNDARY LOCALLY - it asks the server and caches the answer. Progress bars, countdowns and the save affordances in the mission windows all depend on it.
Carries nothing.
Do the same: ask once and cache. Recomputing the week boundary from your own clock will disagree with the server across timezone and daylight-saving boundaries, which is exactly when it matters.
When you may send it
Requires character_loaded observed Raised by: opening a guild-mission window (tier, or ranks-and-categories). The send is GUARDED on a service state enum, so in practice it fetches once per session proven Related messages
You will then receive GuildWeeklyNextResetResponse observed — observed on the wire as a Response, matching a direct reply rather than a push No fields you may set.
  • summary: Asks when the guild's current mission week ends. Empty payload.
  • area: Game.Guild
  • 68 vues
Presents an authentication ticket on a freshly opened game-server socket; always the first frame written on that connection.
Kind request · Area Game.Connection
THE FIRST FRAME ON EVERY GAME-SERVER SOCKET. Nothing else is accepted until it is answered, and the client does not wait for the socket to finish opening before writing it: the message is built inside the connect routine and handed to the connection object while the TCP handshake is still in flight. The connection queues it and flushes it the instant the channel goes live.
WHEN TO SEND IT
There are exactly two moments, and both are the opening of a NEW socket.
1. ENTERING A SERVER. The trigger is NOT the login server's server-selection reply. That reply only hands you three things - a ticket, a host, and a LIST of candidate ports - which the client stores. The client then lets the LOGIN connection close, and only once that socket is gone does it dial the game host and send this message. A capture of a full sign-in therefore shows two connections that do not overlap.
2. TRANSFERRING TO A FIGHT SERVER. A second game connection, opened ALONGSIDE the first, which stays up. The server sends a transfer message carrying its own host, its own ticket and its own port list; the client opens a second socket, sends this message on it, and from then on drives both connections at once. The destination is a dedicated arena server - see ServerType.KOLIZEUM.
THE PORT LIST IS A CANDIDATE LIST, NOT A CHOICE. You are given several ports for one host. The client takes its configured port when that port is in the list and the first one otherwise; on a failed connect it drops that port and retries the next, until the list is empty. The identification request is NOT rebuilt per attempt - it is queued once, on the connection object, and written on whichever attempt succeeds. The number of TCP attempts and the number of identification requests are not the same number.
THE TICKET IS NOT SOMETHING YOU CAN INVENT. It comes from an exchange on an earlier, separate connection, and the two moments above use two DIFFERENT tickets: entering a server uses the one from the server-selection reply, the fight transfer uses the one carried by the transfer message. They are not interchangeable.
ONE SESSION, TWO SOCKETS. Because the fight transfer identifies on a second socket while the first one is still authenticated, "already authenticated" does not mean "must not send this". What is illegal is sending it TWICE ON ONE SOCKET. Scope the rule to the connection, not to the session.
BEWARE THE NAME COLLISION. A message called IdentificationRequest exists in BOTH protocols: one in the Connection protocol (login server) and this one in the Game protocol. They are different messages with different payloads, and a single sign-in sends both.
DO NOT COPY FIELD NUMBERS FROM AN OLDER SCHEMA. This message has been renumbered - the reference build carries the ticket and the locale as fields 1 and 2, the current build does not. Read the numbers off this page.
Acceptance is followed immediately by a burst of state events in the same millisecond - server settings, optional features, account capabilities and rights, trust status - ending with ServerSessionReadyEvent.
When you may send it
Requires transport_established observed Raised by: a client-side state change - one of the two connect routines opening a game-server socket, either entering a server (after the login connection has closed) or transferring to a fight server (a second socket beside the first). The message is built inside that routine and queued on the connection before the TCP handshake finishes, so it leaves as the first frame the moment the socket goes live proven State it changes
Establishes authenticated observed — acceptance opens the session; every later message is gated on it Related messages
You will then receive ServerSessionReadyEvent observed — the session value the challenge exchange is built on; 1 of 1 login capture You will then receive ServerSettingsEvent observed — server identity and settings, in the same inbound burst You will then receive OptionalFeaturesEvent observed — which optional features this server enables You will then receive TrustStatusEvent observed — whether the server considers the client trusted You will receive one of AuthenticationTicketAcceptedEvent observed — the ticket was accepted You will receive one of AuthenticationTicketRefusedEvent observed — the ticket was rejected Fields
#FieldTypeMeaningYou set it 1ticket_keystringThe authentication ticket for THIS connection, issued by the exchange that sent you here.
Two different tickets are in play. Entering a server uses the one carried by the login server's server-selection reply; transferring to a fight server uses the one carried by the transfer message. They are not interchangeable, and neither can be derived from anything you already hold.required 2language_codestringThe client's current locale, e.g. fr or en. The server uses it to localise the text it sends back.
Observed: fr
Read from the client's one global locale at the moment of connecting, so every connection of a session carries the same value.required
  • summary: Presents an authentication ticket on a freshly opened game-server socket; always the first frame written on that connection.
  • area: Game.Connection
  • 125 vues
Asks the server to turn the played character to face a new direction, without moving it.
Kind request · Area Game.Gamemap
Turning is a first-class action in DOFUS, separate from moving: a character can turn on the spot without changing cell. Facing decides which way the sprite looks and which animation set plays, and it matters mechanically - backstab bonuses depend on the relative facing of attacker and target.
DO NOT APPLY THE TURN OPTIMISTICALLY. The server validates it and broadcasts the result to everyone on the map INCLUDING BACK TO YOU, as MapChangeOrientationEvent. The real client waits for that echo, and your world model should too.
IT CARRIES NO ACTOR ID, AND THAT IS DELIBERATE. The server knows who is asking from the connection. You cannot turn anyone but yourself with this message - which is why the outbound half has one member where the inbound half has two.
In the client the action hangs off the right-click menu on your own character (the localisation key is ui.orientCharacter) and off the action-bar banner menu. The equivalent menus for other players and for NPCs do not offer it.
When you may send it
Requires context_ready inferred Raised by: the player picks a facing from the right-click menu on their own character proven Related messages
You will then receive MapChangeOrientationEvent inferred — the server validates and broadcasts the turn to everyone on the map, including back to the requester Fields
#FieldTypeMeaningYou set it 1directionDirectionThe facing to turn to.
A Direction value.required
  • summary: Asks the server to turn the played character to face a new direction, without moving it.
  • area: Game.Gamemap
  • 69 vues
Asks the server what is standing on a map. Without it the map loads empty.
Kind request · Area Game.Gamemap
Turns a loaded map into a playable one. A script that never sends this sees an empty world: no actors, no interactive elements, nothing to walk to.
SEND IT ON EVERY MAP LOAD, ONCE PER MAP - NOT ONCE PER SESSION. The client raises it from its internal map-loaded notification, so it fires again on every teleport, zaap, map change and fight exit.
SEND IT TOGETHER WITH ContextReadyRequest. They live in different protocol areas but the client raises both from the SAME notification, and in a capture they leave back to back carrying the same map id. Sending only one is not something the real client ever does.
USE THE ID OF THE MAP YOU JUST LOADED. The client reads it from its entity service's current map at the moment the map-loaded notification fires - the map named by the MapCurrentEvent that started the load - not from an older cached value.
Note the type mismatch with its sibling: map_id is int32 here and the same value travels as an int64 in ContextReadyRequest. A capture shows both leaving in the same millisecond with 153356290 in each. A width difference is not a different map.
DO NOT SET A CORRELATION ID. The client dispatches this uncorrelated, leaving the envelope id at -1.
ON THE WIRE, THE CAUSE IS MapCurrentEvent - or its instanced form MapCurrentInstanceEvent, which the client feeds into the same map load. The map load this request follows is started by that message: the client's map service receives it, the map renderer loads the map it names, and the loaded-map notification this request hangs off is raised at the end of that load. A script that loads nothing should send this right after either message, with its map id.
When you may send it
Requires character_loaded observed Raised by: the client's map-loaded notification, which fires on every teleport, zaap, map change and fight exit - the writer then sends the id of the map its entity service has just loaded proven Related messages
Answers MapCurrentEvent Answers MapCurrentInstanceEvent You will then receive MapComplementaryInformationEvent inferred — the client asks for a map's contents with this request, and the contents arrive as that event; it is an Event, so match it by arrival rather than by correlation id Reply not yet recovered: on an unknown map id the area declares MapErrorNotFoundRequest, also not recovered. Fields
#FieldTypeMeaningYou set it 1map_idint32The map whose contents are being asked for. (map id)
Range: int32 here; the same id is int64 in ContextReadyRequest
Observed: 153356290
Read from the entity service's current map when the map-loaded notification fires.required
  • summary: Asks the server what is standing on a map. Without it the map loads empty.
  • area: Game.Gamemap
  • 99 vues
Stops a walk in progress and tells the server where you actually ended up.
Kind request · Area Game.Roleplay
STOPS A WALK AND SAYS WHERE YOU ACTUALLY ARE. It is not "cancel my request" - by the time you send it you have already moved partway, and the one value it carries is where you came to rest.
WHEN TO SEND IT
WHEN A WALK YOU ALREADY STARTED IS INTERRUPTED BEFORE IT FINISHES. You send MapMovementRequest with a path, the server accepts it, and then something stops you early - the player clicked elsewhere, a fight started, an obstacle appeared, the player pressed the stop control. That is this message.
DO NOT SEND IT FOR A WALK THAT COMPLETED. A finished walk needs nothing; the server already knows the destination it approved.
SEND THE CELL YOU ARE ACTUALLY ON, NOT THE ONE YOU AIMED AT. This is the whole point of the message and the easiest thing to get wrong. The real client does not send the destination from the path it requested, nor the cell it last announced - it sends the moving entity's own current cell - asked from the entity's physics up to 3.6.12.16, read straight off the entity from 3.7.1.0. If you send the intended destination you are telling the server you completed a walk you interrupted, and your position and its position diverge from that moment on.
A script that walks by sending a path and then aborts must therefore track where it stopped. If you cannot compute that, do not send this message at all - diverging silently is worse than not cancelling.
WHAT COMES BACK
NOTHING DEDICATED. No dumped client waits for a reply. The server reconciles your position through the ordinary actor traffic that follows, so watch your own actor's position rather than expecting an acknowledgement.
BE HONEST ABOUT THE CELL and the correction will be invisible; be optimistic about it and the server will move you back, visibly, later.
When you may send it
Requires context_ready observed Raised by: a client-side state change: a walk being interrupted before it reaches its destination. The client stops the moving entity, asks its physics where it actually is, and reports that cell inferred Related messages
Nothing answers it - send it and move on no dumped client waits for a reply; the server corrects the position through ordinary actor traffic Fields
#FieldTypeMeaningYou set it 1cell_idint32The cell you stopped on.required
  • summary: Stops a walk in progress and tells the server where you actually ended up.
  • area: Game.Roleplay
  • 64 vues
Tells the server the character has finished walking the path it was granted. Empty payload.
Kind request · Area Game.Gamemap
Closes the movement handshake: the walk you were granted is done.
CARRIES NOTHING - SEND IT EMPTY. Four of the dumped builds declare it with no fields at all; the current one pads it with a nine-value enum that NO writer in any dumped build populates. The client constructs this message, sets nothing, and submits it.
Watch that padding rather than dismissing it. If a later build starts populating that enum, this message stops being a bare acknowledgement and becomes a "why did the move end" report - and a script that has hardcoded an empty payload will be sending the wrong thing rather than nothing.
The name comes from one oracle only: Ankama's own type map in an early 3.x build. This message postdates the unobfuscated reference build, so unlike most of this catalogue there is no second source to cross-check the spelling.
When you may send it
Requires context_ready inferred Related messages
Answers MapMovementEvent You will then receive MapMovementConfirmResponse inferred — the server acknowledges and the handshake closes No fields you may set.
  • summary: Tells the server the character has finished walking the path it was granted. Empty payload.
  • area: Game.Gamemap
  • 81 vues
Asks the server to walk the character along a path of map cells.
Kind request · Area Game.Gamemap
Asks to move. YOU ARE ASKING, NOT MOVING - the server decides what actually happens and answers with MapMovementEvent (the walk granted) or MapMovementRefusedEvent (no walk; you are put back on the cell it names).
WALK THE PATH THE SERVER SENDS BACK, NOT THE ONE YOU ASKED FOR. The granted path can be shorter than the requested one, and applying your own path optimistically desynchronises your position from the server's. Everything else you do on the map - reading interactives, attacking, using a zaap - is validated against the server's idea of where you stand.
key_cells is the path as map cell ids, in order, starting from the cell ADJACENT to where you are, not from your current cell. Cell ids are single grid indexes, not coordinate pairs.
map_id must be the map you are actually on. The client reads it from live map state at send time rather than from a cache, and so should you: after a teleport, a stale map id is the difference between a move and a rejected one.
cautious is the careful-walking mode the client derives from its own movement options. It is not a speed setting.
NEVER SEND TWO OF THESE LESS THAN 250 ms APART. The roleplay client stamps the time in milliseconds whenever it sends one, and a walk asked for within 250 ms of that stamp is ignored, not queued - except, it appears, when it re-targets the walk already under way. Faster walk requests are traffic no real client produces.
When the walk finishes, close the handshake with MapMovementConfirmRequest. After a refusal there is no walk to confirm: send no MapMovementConfirmRequest, take the cell the refusal names as your position, and plan again from there.
When you may send it
Requires context_ready inferred Raised by: the player choosing a destination. Two producers build it: the roleplay movement service (four sites, working from EntityPhysics and a validated MapPoint path) and the fight movement service (two sites, built around FightTurn) proven Related messages
You will receive one of MapMovementEvent inferred — the grant: the path the character will actually walk. The client's handler treats this event as the answer to this request You will receive one of MapMovementRefusedEvent inferred — the refusal: the server will not move the character and names the cell it really stands on. The client's handler for it clears the walk under way and snaps the character to that cell Fields
#FieldTypeMeaningYou set it 1key_cellsrepeated int32The requested path, as an ordered list of map cell ids. (map cell ids)
A cell id is a single grid index, not an x/y pair.
The client derives these from an already-validated path, so it never asks for a route it believes is impassable.required 2map_idint64The map the movement is requested on. (map id)
Read from live map state at send time, not from a cached current map.required 3cautiousboolWhether to move in the client's cautious walking mode.
Derived from the player's movement and input options, not from the path.required
  • summary: Asks the server to walk the character along a path of map cells.
  • area: Game.Gamemap
  • 84 vues
Answers an NPC by picking one of the replies it offered.
Kind request · Area Game.Npc
ANSWERS THE QUESTION THE NPC JUST ASKED. One id: the reply you picked.
WHEN TO SEND IT
ONLY WHILE A DIALOGUE QUESTION IS OPEN, and only with a reply id that question actually offered (NpcDialogQuestionEvent.visible_replies). The reply ids are not global constants you can hardcode - each question arrives carrying its own list, and the client never invents one. Sending an id the current question did not offer is not a different answer, it is an invalid one.
THREE WAYS IN, ONE MESSAGE. The real client sends this from a reply button, from confirming the highlighted reply, and from taking the first reply when the dialogue validates itself. All three raise the same intent with the same single value, so a script only needs one path: decide which reply, send its id.
ONE ANSWER PER QUESTION. The dialogue is a turn-taking exchange - answer, wait for what comes back, answer again. Do not queue several replies ahead; the ids of the next question do not exist yet when you send this one.
WHAT COMES BACK
EITHER THE NEXT QUESTION (NpcDialogQuestionEvent) OR THE DIALOG CLOSING - and which one you get is the NPC's decision, not yours. A reply that ends the conversation produces a dialog close rather than another question, so treat "no new question" as a normal outcome and watch for DialogLeaveEvent with the dialogue type, which is how the client learns the exchange is over.
Nothing here is correlated: the envelope uid goes out as -1 and there is no response to match against.
THE SECOND DECLARED MEMBER IS PADDING. No dumped client has ever written it.
When you may send it
Requires context_ready observed Requires npc_dialog_open inferred Raised by: a client-side state change: the player choosing one of the replies the NPC dialogue is showing - by clicking a reply button, by confirming the highlighted one, or by taking the first reply when the UI validates itself. All three raise one intent carrying the reply id inferred Related messages
You will then receive NpcDialogQuestionEvent inferred — the next line of the conversation, when the reply leads somewhere; a reply that ends the conversation closes the dialog instead (DialogLeaveEvent of type DIALOG_DIALOG) Fields
#FieldTypeMeaningYou set it 1reply_idint32The reply you picked, by the id the question offered.required
  • summary: Answers an NPC by picking one of the replies it offered.
  • area: Game.Npc
  • 64 vues
Ask an NPC on the current map to run one of its actions.
Kind request · Area Game.Npc
WHEN TO SEND IT
Send it when the player picks one of the actions an NPC offers - talk, open its shop, and so on. You need three things, and all three must agree:
the NPC's id the contextual id of the NPC ON THIS MAP, not a data id. It is the id the map sent you for that actor, and it is routinely NEGATIVE. Do not invent it and do not carry it across maps. the action id which of that NPC's actions you want. Small integer. the map id the map you are on RIGHT NOW.
Sending it before the map is loaded, with an NPC that is not on that map, or with an action that NPC does not offer, is refused.
WHAT COMES BACK
Nothing addressed to this request, when it works - the action itself answers. A dialogue action (talking to the NPC, using a portal NPC) answers with NpcDialogCreationEvent and then the NPC's first line, NpcDialogQuestionEvent; opening a shop answers with the shop's messages. On refusal the server sends a failure event that carries no payload, so it tells you THAT it failed and never why.
SO DO NOT WAIT ON A REPLY TO THIS MESSAGE. Wait on the action you asked for, and treat the empty failure as your only negative.
WHY THE MAP ID IS IN HERE
It is the server's guard against a stale click: the NPC id alone is ambiguous once you have changed map, and this pins the request to the map the player was actually looking at.
When you may send it
Requires context_ready observed Requires character_loaded inferred Related messages
You will receive one of NpcDialogCreationEvent observed — the success of a dialogue action (talking to the NPC, using a portal NPC): the dialog opens and its first line follows; 1 of 1 capture (action 3 on the Incarnam portal NPC). Other actions answer with their own workflow's messages instead You will receive one of ExchangeNpcShopStartedEvent observed — the success of a merchant's buy/sell action: the shop opens with its stock; 1 of 1 capture (action 1 on NPC -20000, answered 29 ms later) You will receive one of NpcGenericActionFailureEvent inferred — the refusal: an empty event, so it tells you THAT the action failed and never why Fields
#FieldTypeMeaningYou set it 1npc_action_idint32Which of that NPC's actions to run. Small integer.required 2npc_map_idint64The map the player is on. Guards against a stale click.required 3npc_idint32The NPC's contextual id on the current map. Usually negative.required
  • summary: Ask an NPC on the current map to run one of its actions.
  • area: Game.Npc
  • 81 vues
Asks for the market average price of every tradeable item. Empty payload, and the answer is the whole catalogue.
Kind request · Area Game.Exchange
Carries nothing. One request fetches the average price of EVERY tradeable item - the protocol offers no per-item form.
SEND IT ON A SCHEDULE, NOT ON DEMAND. The client runs it from a background loop that fires once at start and then hourly, gated on a persisted timestamp. The staleness test is a CALENDAR-DAY comparison, not an elapsed-hours one: the client stores the last refresh as a UTC tick count and considers the cache stale when the stored date differs from today in year, month or day. A cache written at 23:59 is therefore stale one minute later, and a bot that re-asks on every login regardless is producing a traffic pattern the real client does not.
EXPECT A VERY LARGE ANSWER. The observed reply carried 9711 (gid, price) pairs - effectively the whole catalogue. Asking in a loop is expensive at both ends and unmistakable in a capture.
DO NOT SET A CORRELATION ID. The client sends this uncorrelated, leaving the envelope id at -1, and the answer comes back as an EVENT rather than a response - so there is nothing to correlate against. Match ObjectAveragePricesEvent by arrival.
There is a failure event in the naming oracles that would answer this instead, but it is not recovered and has no signature here. Watch for an unexpectedly empty reply after asking.
When you may send it
Requires character_loaded inferred Raised by: a background loop that fires at start and then hourly, gated on a persisted timestamp compared by CALENDAR DAY - a cache written at 23:59 is stale a minute later inferred Related messages
You will then receive ObjectAveragePricesEvent observed — the answer to this request; the observed reply carried 9711 price pairs No fields you may set.
  • summary: Asks for the market average price of every tradeable item. Empty payload, and the answer is the whole catalogue.
  • area: Game.Exchange
  • 66 vues
Destroys a quantity of one inventory item. The item is gone; there is no undo and no confirmation step on the wire.
Kind request · Area Game.Inventory
DESTRUCTIVE AND IRREVERSIBLE. This is the destroy-item action, not a move and not a drop. The items are consumed by the server with no confirmation exchange: by the time you could change your mind the message is already sent.
IT HAS A TWIN THAT DROPS THE ITEM ON THE GROUND INSTEAD. A sibling request in the same file wraps the identical ObjectUidWithQuantity payload and means something completely different. Their wire shapes are indistinguishable, so verify you are constructing THIS message by name; a mistake here is not caught by any type checker.
Address the stack by ObjectItem.uid, never by ObjectItem.gid. A gid either names no stack or names a different one, and the request is not rejected for being nonsense.
quantity is how many to destroy, not how many to leave. Sending the stack's full quantity destroys the stack.
When you may send it
Requires character_loaded inferred Raised by: the player confirms the destroy prompt on an inventory item proven Related messages
Reply not yet recovered: the server acknowledges with an inventory update naming the new quantity. That message has no signature yet, so treat the destroy as unconfirmed until the next InventoryContentEvent or quantity update you can read. Fields
#FieldTypeMeaningYou set it 1objectObjectUidWithQuantityWhich stack to destroy and how many units of it.
The current build declares this type twice in the record; only this member is ever populated.required
  • summary: Destroys a quantity of one inventory item. The item is gone; there is no undo and no confirmation step on the wire.
  • area: Game.Inventory
  • 77 vues
Latency probe. Its automatic sender only fires when the player has touched an input device, so it is not a heartbeat.
Kind request · Area Game.Connection
Measures round-trip time to the game server: send it, wait for PongEvent, keep the delta.
TWO SENDERS, AND ONLY ONE OF THEM IS A TIMER.
THE AUTOMATIC PROBE sends quiet = true. A timer re-arms itself every INTERVAL ms, but a tick only sends if the player touched an input device since the previous tick:
every INTERVAL ms: if input_seen_since_last_tick: input_seen_since_last_tick = false send PingRequest(quiet = true) re-arm INTERVAL is 5 seconds when the client's fast-ping option is on and 10 minutes when it is off. There is no third value, no jitter and no back-off.
THE CHAT CONSOLE COMMAND 'ping' sends quiet = false, once, immediately, with no gate at all. Its sibling 'aping' prints the stored average and sends nothing.
THREE PROPERTIES OF THE INPUT GATE DECIDE WHAT YOUR TRAFFIC LOOKS LIKE. It is a LATCH, not a counter - ten thousand input events between two ticks produce one ping, not ten thousand. It is CONSUMED by the tick, so two consecutive pings need input in two separate intervals. And it is read BEFORE the send, so the first tick after an idle stretch is silent.
WHAT COUNTS AS INPUT IS NARROWER THAN IT LOOKS. The latch is set only while a keyboard key or a mouse button is held, or a movement axis is off centre. Moving the mouse without pressing anything does not set it, and neither does giving the window focus back. Gameplay does not set it either: a character walking a route under script control produces no input at all.
A CLEAN PERIODIC PING STREAM IS A STRONGER ANOMALY THAN SILENCE. A real client cannot produce one - with the input devices untouched it sends almost never. A capture of an active session shows pings roughly ten seconds apart while the player was moving: irregular, not clockwork. If your script never touches an input device, the faithful behaviour is to send this rarely, or not at all. The gate is a traffic-shape rule, not a legality rule - the server answers a ping sent at any moment.
ONE PING AT A TIME. The client keeps a single outstanding send timestamp: stamped on send, cleared by the reply. A reply that arrives with no outstanding send is discarded and produces no sample, so pipelining pings gets you fewer measurements, not more.
WHAT HAPPENS IF NOTHING COMES BACK. One second after each send the client raises its lag indicator, and lowers it again when the reply lands. Nothing is retransmitted and nothing is torn down - the exchange simply stays unanswered.
THE SAMPLES ARE NOT DECORATIVE. Each round trip is appended to a rolling buffer of the last 50, and the average of that buffer is the number a real client reports when the server polls with BasicLatencyStatsEvent. A script that never pings has no honest value to put in BasicLatencyStatsRequest.
When you may send it
Requires authenticated observed Raised by: two independent senders. A timer that re-arms itself every 5s (fast ping on) or 10min (off) and sends ONLY if raw input arrived since the previous tick, clearing that latch as it fires; and the chat console command 'ping', which sends once, immediately, with no gate inferred Related messages
You will then receive PongEvent observed — the reply that closes the measurement; answered ~30ms later, 2 of 2 observations in one session Fields
#FieldTypeMeaningYou set it 2quietboolWhether the measurement stays silent. The server echoes it back unchanged in the reply.
The automatic probe sends true; the chat console command sends false. The difference is not server-side - the flag comes back in PongEvent.quiet, and a client that receives false PRINTS the measured round-trip into the chat window. Send false only if you mean to imitate a player who typed the command.required
  • summary: Latency probe. Its automatic sender only fires when the player has touched an input device, so it is not a heartbeat.
  • area: Game.Connection
  • 71 vues
Sets the character's own availability, with an optional free-text message.
Kind request · Area Game.Social
Sets your own availability - see Status for what the values mean.
DO NOT APPLY IT LOCALLY AND ASSUME IT TOOK. The server echoes the change back as PlayerStatusUpdatedEvent; that echo is what makes it real. There is a sibling error event in the naming oracles for a rejected change, declared empty and not recovered here.
status carries both the state and the optional free text; see CharacterStatus.
STATUS_IDLE IS THE CLIENT'S TO SET, NOT YOURS. The real client sets idle when it notices inactivity. Announcing AFK is a deliberate player action; announcing idle while actively playing is a claim the real client does not make.
When you may send it
Requires character_loaded observed Raised by: the player picks an availability from the status control inferred Related messages
You will then receive PlayerStatusUpdatedEvent inferred — the server broadcasts the new status, echoing it back to the sender as well Fields
#FieldTypeMeaningYou set it 1statusCharacterStatusThe availability state to adopt, plus its optional free text.
A CharacterStatus.required
  • summary: Sets the character's own availability, with an optional free-text message.
  • area: Game.Social
  • 71 vues
Opens the character-deletion flow and asks what the server needs to confirm it. Deletes nothing.
Kind request · Area Game.Character
STEP 1 OF 3. IT DELETES NOTHING. It asks the server what confirming the deletion will require.
1. PrepareCharacterDeletionRequest you ask 2. CharacterDeletionPrepareEvent the server states the terms 3. CharacterDeletionRequest the deletion actually happens Do not send step 3 without reading step 2: whether a secret answer is required is decided there, per character.
Padding varies between builds; the id is the member named here.
When you may send it
Requires authenticated observed Raised by: the player chooses to delete a character on the selection screen proven Related messages
You will then receive CharacterDeletionPrepareEvent inferred — the server answers with the character's name and whether a secret answer is required Sequence
Step character_deletion.1 inferred — of 3 steps; the flow is a fixed ask / terms / confirm exchange
Fields
#FieldTypeMeaningYou set it 1character_idint64The character the player asked to delete. (character id)required
  • summary: Opens the character-deletion flow and asks what the server needs to confirm it. Deletes nothing.
  • area: Game.Character
  • 69 vues
Adds a quest, or one objective of it, to the followed list shown in the quest tracker.
Kind request · Area Game.Quest
ADDS A QUEST TO THE TRACKER. Its opposite number removes one, and the two are the only difference between two otherwise identical messages - read the section below before you pick one.
WHEN TO SEND IT
WHEN YOU START FOLLOWING SOMETHING YOU ARE NOT ALREADY FOLLOWING. That second half matters. The real client keeps its own list of followed quest ids and checks it before sending: if the quest is already there it sends the UNFOLLOW message instead, and if it is not, it sends this one and adds the id. So the client never sends a follow for a quest it already follows.
Do the same. Track what you follow, and send this only for a quest you are not tracking - otherwise you and the server disagree about the list, and the client UI that reads it back will disagree with both.
ONE INTENT, TWO MESSAGES. Both come out of the same UI action and the same client method; which one goes out is decided by that list check. There is no "toggle" message.
WHAT TO PUT IN IT
THE QUEST, AND OPTIONALLY ONE OBJECTIVE. Send -1 as the objective to follow the quest as a whole rather than a specific step - that is the sentinel the client itself tests against, and it is what a capture of "follow this quest" shows.
Both values are 32-bit on the wire but the client carries them as 16-bit internally, so they are small ids, not handles.
WHAT COMES BACK
NOTHING DEDICATED. The followed list is state the server mirrors; no dumped client waits for a reply to this message. If you need confirmation, it arrives as the quest data the server pushes, not as an answer to this request.
When you may send it
Requires context_ready observed Raised by: a client-side state change: the player turning tracking ON for a quest or one of its objectives in the quest UI. The screen raises one intent carrying the quest, the objective and an on/off flag, and the writer checks its own followed-list first - it sends this only when the quest is not already in that list inferred Related messages
Nothing answers it - send it and move on no dumped client waits for a reply; the followed list is client state the server mirrors Fields
#FieldTypeMeaningYou set it 3quest_idint32The quest to follow.required 4objective_idint32Which objective of it to follow, or -1 to follow the quest itself.required
  • summary: Adds a quest, or one objective of it, to the followed list shown in the quest tracker.
  • area: Game.Quest
  • 68 vues
Asks which step of one quest the character is on, and what that step's objectives are.
Kind request · Area Game.Quest
Asks about ONE quest. There is no "give me every quest's current step" form - the journal listing and this per-quest detail are separate exchanges.
quest_id is the quest to ask about. Take it from the journal rather than hardcoding it.
The answer is an EVENT, not a Response, so there is nothing to correlate against - match QuestStepInformationEvent by arrival and by the quest id it carries.
When you may send it
Requires character_loaded observed Raised by: asking about one quest - and again whenever its step changes, if you want the new objectives inferred Related messages
You will then receive QuestStepInformationEvent inferred — the quest service's handler treats that event as the answer Fields
#FieldTypeMeaningYou set it 1quest_idint32Which quest to ask about. (quest id)required
  • summary: Asks which step of one quest the character is on, and what that step's objectives are.
  • area: Game.Quest
  • 64 vues
Asks for a one-shot token that lets the next connection skip full authentication. Empty - the message is the ask.
Kind request · Area Game.Connection
CARRIES NO PAYLOAD. There is nothing to fill in - constructing it and sending it IS the request. Send it BEFORE you hand this connection over, then read ReloginTokenEvent.
WHEN TO SEND IT
WHEN YOU ARE ABOUT TO LEAVE THIS GAME SERVER, and not otherwise. In the real client every path into it is a menu confirmation:
go back to server choice -> ReloginRequest confirm a change of server -> ReloginRequest confirm a change of character -> ReloginRequest confirm server + character -> ReloginRequest Nothing in gameplay sends it. It is not a keepalive, it is not periodic, and it has nothing to do with PingRequest despite sitting beside it in the protocol.
ONE AT A TIME. The client refuses to send a second request while an answer is still outstanding - it raises an error popup instead of asking again. Do not pipeline this and do not retry it while you are still waiting; if you never got an answer to the first one, the connection is the problem, not the request.
THE CLIENT PARKS WHAT YOU ASKED FOR. It remembers the action that provoked the request, sends this, and only replays that action once the token has been stored. That ordering is the whole point of the exchange: if you act on the server change before the answer lands, you leave without the token you asked for and gain nothing.
WHAT COMES BACK
ReloginTokenEvent, with a grant flag and a token. Both branches are real - read that record before implementing either.
MATCH IT BY TYPE, NOT BY UID. This goes out on the uncorrelated send path, so its envelope uid is -1 and there is no response to pair against it. Watch for the event.
SENDING IT IS OPTIONAL. Skip it and nothing breaks here; the next connection simply has to authenticate in full instead of presenting a token. What is not optional, if you do send it, is waiting for the answer before you move.
When you may send it
Requires authenticated observed Raised by: a client-side state change: one of three 'leave this game server' intents raised by the menu screens - go back to server choice, go to a chosen server, or go to a chosen server to play a named character. The writer parks the intent, sends this request, and replays it only once the answer has been stored inferred Related messages
You will then receive ReloginTokenEvent observed — the server answers with a token grant or refusal No fields you may set.
  • summary: Asks for a one-shot token that lets the next connection skip full authentication. Empty - the message is the ask.
  • area: Game.Connection
  • 72 vues
Answers the server's sequence poll with how many of those polls this connection has received.
Kind request · Area Game.Basic
Answers SequenceNumberEvent. One integer: a counter this connection keeps.
WHEN TO SEND IT
ONCE PER POLL, IMMEDIATELY, AND FROM NOWHERE ELSE. The client builds this message in exactly one place - inside the handler for the poll - and replies unconditionally, before anything else looks at the event. There is no timer and no proactive path.
WHAT THE COUNTER ACTUALLY COUNTS
NOT INBOUND MESSAGES. NOT EVENTS OF EVERY KIND. It counts the SequenceNumberEvent polls that have arrived on THIS connection, and nothing else touches it. The whole rule is two lines:
when the socket becomes active: n = 0 when a poll arrives: n = n + 1, then reply with n Three consequences, all of them visible to the server:
IT RESTARTS AT EVERY RECONNECTION. The reset is bound to the socket becoming active, not to logging in, so a reconnect starts again from zero. Carrying a count across connections is wrong.
THE FIRST REPLY CARRIES 1, NEVER 0. The counter is incremented before the reply is built.
EACH CONNECTION HAS ITS OWN. If you hold two game sockets at once (see IdentificationRequest), each counts its own polls independently. There is no shared total.
A bot that hard-codes a constant, counts the wrong thing, restarts mid-connection or carries the number across a reconnect is producing traffic no real client produces - and this is the one number in the exchange the server can recompute exactly, because it sent every poll itself.
THIS COUNTER IS NOT THE ENVELOPE UID
They are different numbers living in different places, and confusing them is the easy mistake here. The counter is the payload. The uid is transport-level - and for this particular message the client does not allocate one at all: it writes the reply straight down the connection rather than through the normal request path, so the envelope goes out with the uid set to -1. BasicLatencyStatsRequest, answering the poll that arrives in the same frame, does carry a real uid. Two replies to one frame, two different envelope shapes.
When you may send it
Requires authenticated observed Related messages
Answers SequenceNumberEvent Fields
#FieldTypeMeaningYou set it 1numberint32How many sequence polls this connection has received, counting the one being answered. (poll count)
Range: starts at 1 on each new connection and increases by one per poll
It counts THESE polls only, not inbound messages in general, and it is reset when the socket becomes active rather than when you log in.required
  • summary: Answers the server's sequence poll with how many of those polls this connection has received.
  • area: Game.Basic
  • 70 vues
Tells the server which language community the character chats on.
Kind request · Area Game.Social
DOFUS segregates the public chat by language, and this picks which segment you are in. It decides which community channel you read and write on - see Channel.COMMUNITY.
The server answers with CommunityChannelEvent carrying the value it ACCEPTED, which is not necessarily the one you asked for. Read the answer rather than assuming.
A VOLLEY OF ChannelUpdateEvent FOLLOWS IMMEDIATELY. Changing community re-states the character's channel subscriptions, so expect your channel mask to be rewritten right after. Do not race it.
When you may send it
Requires character_loaded observed Raised by: the player changing the chat-language control, and once on entering the world with the persisted account option. One user decision, one request; never on a timer proven Related messages
You will then receive CommunityChannelEvent observed — the server states back the community it accepted, then re-states the character's channel subscriptions Fields
#FieldTypeMeaningYou set it 1communityint32The community to chat on.
Range: -1 to 4
-1 unset, 0 French, 1 English/international, 2 Spanish, 3 Portuguese, 4 German.required
  • summary: Tells the server which language community the character chats on.
  • area: Game.Social
  • 70 vues
Asks for the married partner's identity, status and map position.
Kind request · Area Game.Social
It is one of a FIXED FOUR-REQUEST BURST the client fires once per entry into the world, straight after asking for the game context. The client's own name for the routine survives obfuscation: SendRequestAfterCharacterLoaded. The order is constant:
ContextCreationRequest (the context first) 1. FriendListRequest 2. AcquaintanceListRequest 3. SpouseInformationRequest 4. GuildInformationRequest That order is not guessed from traffic: it is the order the routine allocates the four objects in, and a live capture reproduces it exactly - the first three land inside the same millisecond, the guild request three milliseconds later.
SEND IT ONCE, AT THAT POINT. NEVER POLL IT. The trigger is "the character finished loading", not a timer.
The client sends it unconditionally, married or not - it does not check first.
Carries nothing.
When you may send it
Requires character_loaded observed Related messages
Reply not yet recovered: the spouse information arrives as an event that has no signature here yet. Sequence
Step post_character_load.3 observed — of 4 requests, in the order the client's own routine allocates them
No fields you may set.
  • summary: Asks for the married partner's identity, status and map position.
  • area: Game.Social
  • 75 vues

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.