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
Asserts the complete set of chat channels the character is on, as a subscribe list and an unsubscribe list.
Kind request · Area Game.Chat
A COMPLETE STATE ASSERTION, NOT A DELTA. The client enumerates every channel it can map and puts each one into exactly one of the two lists. A channel you leave out of both is not "unchanged" as far as the real client's traffic shape is concerned - it simply never happens.
So: build both lists from your full channel model, every time. Sending a one-element subscribe list is a shape the real client does not produce.
subscribe is what you want on, unsubscribe what you want off, and together they partition the mappable channels. The roles are read from the writer's own branch polarity, not from field order.
The reference build had a singular subscribe-one-channel request instead; the batch form replaced it before the earliest dumped 3.x build, so there is no unobfuscated declaration for this one.
When you may send it
Requires character_loaded observed Raised by: the channel set changing; the writer always walks every mappable channel, so there is no incremental form proven Related messages
Reply not yet recovered: the server re-states the resulting subscriptions through ChannelUpdateEvent and ChatChannelsEnabledEvent; whether both arrive depends on what actually changed, so react to what comes rather than waiting. Fields
#FieldTypeMeaningYou set it 1subscriberepeated ChannelThe channels the character wants to be on.
Element type Channel.
Name ours: beta has no such message and GameMapping names types only.required 2unsubscriberepeated ChannelThe channels the character wants off.
Element type Channel. Together with subscribe this is a complete partition.
Name ours: beta has no such message and GameMapping names types only.required
  • summary: Asserts the complete set of chat channels the character is on, as a subscribe list and an unsubscribe list.
  • area: Game.Chat
  • 71 vues
The client telling the server it found a mod loader. Empty on purpose.
Kind request · Area Game.Client.Verification
THE CLIENT'S ANTI-TAMPER TELLING THE SERVER IT FOUND A MOD LOADER. It is sent ONLY on a positive detection and it carries no payload at all: the fact that it was sent IS the whole report.
========================================================================= WHAT THE CLIENT ACTUALLY LOOKS FOR =========================================================================
Everything below is decompiled from 3.6.10.10, not inferred. The scan runs against the GAME INSTALL ROOT, computed as
Application.streamingAssetsPath + "/../../" CHECK 1 - LOADER DIRECTORIES. It tests whether any of these exists directly under that root, and stops at the first hit:
MelonLoader BepInEx dotnet MelonLoader and BepInEx are the two mainstream Unity mod loaders; dotnet is the runtime folder they install beside themselves.
CHECK 2 - MANAGED PROXY ASSEMBLIES. If no directory matched, it recursively enumerates *.dll under the same root (SearchOption.AllDirectories) and flags any file whose name without extension is one of:
Core Animator2D Il2Cpp__Generated UnityEngine THIS IS THE CLEVER HALF, AND IT IS WORTH UNDERSTANDING. Dofus is an IL2CPP build: it ships ONE native GameAssembly.dll and no managed assemblies with those names. Those four files are what an IL2CPP interop layer GENERATES when someone attaches a loader to the game - the managed proxies a modder needs in order to write code against Core, UnityEngine and the generated glue. Their presence on disk is therefore evidence of tooling rather than of a modified game, and the check finds a prepared modding environment even when nothing is injected at run time.
The scan is deliberately gentle: it awaits UniTask.NextFrame() between files, so it walks the tree one entry per frame rather than stalling the game.
========================================================================= WHEN IT IS SENT, AND WHEN IT IS NOT =========================================================================
Either check firing calls the same reporter, which sends this message and stops. Neither check firing sends nothing at all. A clean install is therefore SILENT - which is why this message will not appear in an ordinary capture, and why its absence carries no information.
The whole routine is also gated on a configuration value read from the client's configuration service: if that value is 4 or greater the scan returns immediately without checking anything.
========================================================================= IT DELIBERATELY TELLS THE SERVER NOTHING ELSE =========================================================================
The client computes a reason internally - "detected dir" or "detected DLLs" - and then DISCARDS it. The reporter takes that string as a parameter and the async method that actually sends this message has no string field at all, so the reason never reaches the wire.
So the server learns exactly one bit: this client tripped the check. It does not learn which loader, which file, or which of the two checks fired. That is consistent with the message having no members in the first place - it is not an empty message that happens to mean something, it is a deliberate one-bit signal.
========================================================================= WHERE IT SITS IN THE PROTOCOL =========================================================================
It belongs to Game.Client.Verification, and it is the ODD ONE OUT. Every other member of that area is a REPLY or a server-driven prompt:
ServerVerificationEvent server obliges the client to identify itself ClientIdRequest client answers with a fresh commitment ClientChallengeInitRequest client publishes its long-lived public key ServerChallengeEvent server's challenge ClientChallengeProofRequest client's proof, closing the handshake FileCheckEvent server names a game file to measure FileCheckRequest client returns the measurement CheckType which measurement: byte length, or a checksum Those are a three-step proof-of-identity handshake plus an on-demand file-integrity probe, and every one of them is started by the server. THIS message is the only one the client raises on its own initiative, unprompted, and the only one that reports an observation rather than answering a question.
ServerSessionReadyEvent shares the same generated .proto file but is documented under Game.Connection, because it belongs to the connection handshake rather than to verification.
========================================================================= IF YOU ARE WRITING A CLIENT =========================================================================
There is nothing to fill in and nothing to wait for - the send is fire-and-forget from an async void, and no client code awaits a reply.
A well-behaved client never sends it. Sending it volunteers a report about yourself, so the correct behaviour for a reimplementation is simply to never emit it. Note also what it does NOT do: it does not scan process memory, does not enumerate loaded modules, and does not hash anything - it is a filesystem check and nothing more. File integrity is a separate channel, and the server drives that one through FileCheckEvent.
When you may send it
Requires transport_established inferred Related messages
Nothing answers it - send it and move on nothing in the client waits on a reply; the send is fire-and-forget from an async void
  • summary: The client telling the server it found a mod loader. Empty on purpose.
  • area: Game.Client.Verification
  • 74 vues
What the account is allowed to do: whether it may create a character, whether the tutorial is offered, and its staff role.
Kind event · Area Game.Account
Read-only session state describing what this account may do. Nothing is gated on having processed it - you record it and move on.
can_create_new_character USED TO BE A BOOL AND IS NOW A THREE-STATE ENUM. Measured across the dumped builds:
3.5.3.1 bool, bool, Hierarchy 3.5.17.26 bool, bool, Hierarchy, int64 3.6.10.10 CanCreateNewCharacter, bool, Hierarchy That is a real protocol change, verified against what the client reads, not a recovery gap - which is why this record is documented for the current build and does not describe the older ones. Code written against the boolean will misread the enum: value 1 is a REFUSAL, and as a boolean it reads as true.
status is the account's staff role - see Hierarchy. On an ordinary account it is the player role and stays that way.
When you may send it
Requires authenticated observed Related messages
Unsolicited - nothing you send causes this the server pushes it during login and character selection; there is no request for it Fields
#FieldTypeMeaningYou set it 1tutorial_availableboolWhether the tutorial is offered to this account.never 2statusHierarchyThe account's role in the staff hierarchy.
A Hierarchy value. Ordinary accounts carry the player role.never 3can_create_new_characterCanCreateNewCharacterWhether the account may create another character, and if not, why.
A CanCreateNewCharacter value.
WAS A BOOL BEFORE THIS BUILD. Do not read it as one - value 1 means refused.never
  • summary: What the account is allowed to do: whether it may create a character, whether the tutorial is offered, and its staff role.
  • area: Game.Account
  • 82 vues
When the account's subscription ends, as Unix time in seconds; 0 means not subscribed.
Kind event · Area Game.Account
Tells the client when the account's subscription ends.
WHAT TO DO WHEN YOU RECEIVE IT
1. READ subscription_end_date AS UNIX TIME IN SECONDS (UTC). The official client adds it as seconds to 1970-01-01 UTC and converts the result to local time. 2. TREAT 0 AS "NOT SUBSCRIBED". The client stores the earliest possible date instead of converting it. Zero is also the protobuf default, so an absent field reads the same way. 3. SEND NOTHING BACK. The client only updates its account state and tells its interface the subscription changed.
DO NOT CONFUSE IT WITH AccountSubscriptionElapsedDurationUpdateEvent: one int64 in the same account file, which the client stores as-is and never reads as a date.
The official client truncates the value to 32 bits before converting it, which holds until 2038.
When you may send it
Requires authenticated inferred Related messages
Unsolicited - nothing you send causes this the server pushes account state; no request asks for it Fields
#FieldTypeMeaningYou set it 1subscription_end_dateint64When the account's subscription ends. (Unix time, seconds (UTC))
0 means not subscribed; the client stores the earliest possible date for it.never
  • summary: When the account's subscription ends, as Unix time in seconds; 0 means not subscribed.
  • area: Game.Account
  • 68 vues
The account's permission flags for this session, as an opaque block of booleans (five; four from 3.7.1.0).
Kind event · Area Game.Account
Pushed during account setup. You receive it, record it, and never reply - nothing in the protocol is gated on having processed it.
THE FLAGS ARE NOT INDIVIDUALLY RECOVERED and are deliberately left unnamed. There are five of them up to 3.6.12.16 and four from 3.7.1.0. Every line of evidence that names things elsewhere in this catalogue fails here: the unobfuscated reference build has no account-rights type in the game protocol, the early 3.x name map has none either, and the client's handlers branch only on the BLOCK's presence, never on an individual flag. Read them positionally as opaque flags, or ignore them - see Rights.
UP TO 3.6.12.16 THE DECLARATION CARRIES TWO FIELDS OF THE SAME NESTED TYPE and only one is ever read. Five consumers across two services all read the same member and never touch the other, which is what makes the named one the real one. From 3.7.1.0 the second copy is gone and a repeated string sits beside the block instead; no consumer loads it, so ignore it.
This record describes the current build. Earlier builds either lack the message or carry a different shape.
When you may send it
Requires authenticated observed Related messages
Unsolicited - nothing you send causes this no client writer constructs it in any dumped build and there is no matching request message Fields
#FieldTypeMeaningYou set it 2rightsRightsThe account's permission-flag block.
See Rights. The only member any client consumer reads.
The declaration carries a second field of the identical type that nothing reads.
Name ours: no build names this field (the type-name table names types only).never
  • summary: The account's permission flags for this session, as an opaque block of booleans (five; four from 3.7.1.0).
  • area: Game.Account
  • 74 vues
One visible actor: who it is, where it stands, and what it looks like.
Kind struct · Area Game.Common
The element of GameRolePlayShowActorsEvent, and reused by the map-complementary snapshot and by fight synchronisation - so the same record describes an actor in roleplay and in combat.
actor_id IS THE HANDLE FOR EVERYTHING AFTERWARDS. Every later event that moves, turns, animates, addresses or removes this actor names it by this id. Index your world model by it.
disposition is where the actor stands and faces - see EntityDisposition. actor_information carries the appearance (EntityLook) plus a oneof selecting what KIND of actor it is: a named character, a monster group, an NPC, a prism, a portal, a tax collector, or a fighter. Branch on that oneof; it is what tells a monster apart from a player.
NOTHING ABOUT THE LAYOUT IS STABLE. Field numbers move in every direction across the dumped builds and the record is padded with live-looking decoys. Read by name.
Not sent on its own — it travels inside the actor-list events. proven
Used by
FightFighterRefreshEvent FightFighterShowEvent FightSynchronizeEvent GameRolePlayShowActorsEvent MapComplementaryInformationEvent SpawnInformation SummonsByActor Fields
#FieldTypeMeaningYou set it 1actor_idint64Server-assigned id of this actor, unique within the current context. (actor id)
Every later event about this actor names it by this id.never 2dispositionEntityDispositionWhere the actor stands and which way it faces.
See EntityDisposition.never 3actor_informationActorInformationThe actor's appearance and what kind of actor it is.
Carries an EntityLook plus a oneof selecting a roleplay actor or a fighter - branch on it.never
  • summary: One visible actor: who it is, where it stands, and what it looks like.
  • area: Game.Common
  • 82 vues
Which alignment a character belongs to: none, neutral, Bonta or Brakmar.
Kind enum · Area Game.Common
The five alignment values, carried by AlignmentInformation. Every dumped build declares exactly five values numbered 0 to 4 in this order, so the numbering is the real wire contract.
ALIGNMENT DECIDES WHO MAY ATTACK YOU. A script that walks through contested territory should read this on other characters, not just on its own.
A live capture of an ordinary character carried NEUTRAL.
Not sent on its own — an enum is never sent on its own. inferred
Used by
AlignmentInformation FightTeamInformation MonsterGroupActor PartyMemberInformation Values
ValueNumberMeaning UNKNOWN0Unset or unrepresentable. WITHOUT1No alignment. NEUTRAL2Neutral. This is what a live capture of an ordinary character carried. ANGEL3Aligned with Bonta. EVIL4Aligned with Brakmar.
  • summary: Which alignment a character belongs to: none, neutral, Bonta or Brakmar.
  • area: Game.Common
  • 64 vues
The character's alignment, alignment level and grade, and honour standing, carried on the character sheet.
Kind struct · Area Game.Common
The alignment half of the character sheet. The client copies every member into one alignment record that the character sheet, tooltips and the aggression menu read.
alignment is the side - see Alignment. alignment_grade is the grade that picks the wings drawn on tooltips; 0 means no wings. alignment_quest_number is what the alignment tab shows as the alignment LEVEL; the tab treats 20 and above as the top rank.
character_level is the CHARACTER's level, not an alignment value: a level 3 character receives 3. It is an int32 on every Dofus 3 build.
HONOUR LIVES IN AlignmentExtendedInformation, together with the attackability status.
THE REFERENCE BUILD'S character_id IS GONE. No Dofus 3 build carries it here; do not look for an id in this record.
Not sent on its own — it is only ever carried by CharacterCharacteristics. inferred
Used by
CharacterCharacteristics FightCharacterInformation Humanoid Fields
#FieldTypeMeaningYou set it 1character_levelint32The character's own level. (character level)
int32 on every Dofus 3 build (int64 in the reference build).never 2alignmentAlignmentWhich alignment the character belongs to.
An Alignment value.never 3extended_informationAlignmentExtendedInformationHonour standing and attackability.
See AlignmentExtendedInformation.never 4alignment_quest_numberint32The alignment level, shown on the alignment tab.
The tab treats 20 and above as the top rank.never 5alignment_gradeint32The alignment grade that selects the wings drawn on the character.
0 means no wings are drawn.
The client keeps it in a single byte.never
  • summary: The character's alignment, alignment level and grade, and honour standing, carried on the character sheet.
  • area: Game.Common
  • 73 vues
An anomaly has just opened in a subarea.
Kind event · Area Game.Anomaly
An anomaly opened. The client turns it into a chat announcement carrying a clickable travel link to the place.
IT ONLY REPORTS OPENINGS. There is no matching "closed" event on this message - closures come through AnomalyStateEvent with its open flag false. A script that tracks anomalies from this message alone accumulates anomalies that ended hours ago.
It carries the subarea and nothing else. For the reward bonus and closing time you need the board - see AnomalySubareaInformationRequest.
When you may send it
Requires character_loaded observed Related messages
Unsolicited - nothing you send causes this the server announces openings as they happen Fields
#FieldTypeMeaningYou set it 1subarea_idint32Which subarea the anomaly opened in. (subarea id)never
  • summary: An anomaly has just opened in a subarea.
  • area: Game.Anomaly
  • 76 vues
One subarea's anomaly is now open or closed, with the time it closes.
Kind event · Area Game.Anomaly
The delta for one subarea, and THE ONLY MESSAGE THAT REPORTS A CLOSURE - AnomalyOpenedEvent only ever announces openings. open false is how an anomaly ends.
Apply it to the board you got from AnomalySubareaInformationRequest, keyed by subarea_id.
closing_time tells you when the anomaly ends, so you can decide whether it is worth travelling to before it does.
The message declares a second int64 beside closing_time; the named one is the one the client actually loads.
When you may send it
Requires character_loaded observed Related messages
Unsolicited - nothing you send causes this the server publishes anomaly state changes as they happen Fields
#FieldTypeMeaningYou set it 1closing_timeint64When the anomaly closes.
The record declares a second int64 beside this one that the client does not read.never 2openboolWhether an anomaly is now in this subarea.
FALSE IS A CLOSURE, and this is the only message that reports one.never 3subarea_idint32Which subarea changed. (subarea id)never
  • summary: One subarea's anomaly is now open or closed, with the time it closes.
  • area: Game.Anomaly
  • 75 vues
One subarea's anomaly state: whether one is there, what bonus it grants and when it closes.
Kind struct · Area Game.Anomaly
One row of the board, declared nested inside its event.
READ has_anomaly, NOT THE ROW'S EXISTENCE. Rows are sent for subareas with no anomaly, so a script that treats every row as an anomaly walks to empty subareas.
reward_rate is the bonus granted while an anomaly is there - the client shows it as an experience and loot bonus. It is what ranks one anomaly against another.
subarea_id and reward_rate ARE BOTH int32 AND NOTHING ON THE WIRE SEPARATES THEM - they are told apart only by which slot of the client's row object each lands in. Read them by name.
Not sent on its own — it is only ever a row of AnomalySubareaInformationEvent.subareas. inferred
Used by
AnomalySubareaInformationEvent Fields
#FieldTypeMeaningYou set it 1has_anomalyboolWhether an anomaly is currently in this subarea.
THIS, not the row's presence, is what says an anomaly is there.never 2reward_rateint32The bonus granted while an anomaly is in this subarea.
Shown by the client as an experience and loot bonus.never 3subarea_idint32Which subarea this row describes. (subarea id)
Same width as reward_rate; nothing but the recovered name separates them.never 5anomaly_closing_timeint64When the anomaly closes.
The client counts down to it.never
  • summary: One subarea's anomaly state: whether one is there, what bonus it grants and when it closes.
  • area: Game.Anomaly
  • 71 vues
The whole anomaly board: one row per subarea with its anomaly state, reward bonus and closing time.
Kind event · Area Game.Anomaly
The answer to AnomalySubareaInformationRequest.
ROWS ARE SENT FOR SUBAREAS WITH NO ANOMALY TOO. The row's PRESENCE means nothing; AnomalySubareaInformation.has_anomaly is what says whether one is there. Filtering by presence gives you every subarea in the game.
Each row is an AnomalySubareaInformation. Replace your board wholesale, then apply AnomalyStateEvent deltas on top of it.
When you may send it
Requires character_loaded observed Related messages
Arrives after AnomalySubareaInformationRequest Fields
#FieldTypeMeaningYou set it 1subareasrepeated AnomalySubareaInformationOne row per subarea.
Element type AnomalySubareaInformation. Rows exist for subareas without an anomaly too.never
  • summary: The whole anomaly board: one row per subarea with its anomaly state, reward bonus and closing time.
  • area: Game.Anomaly
  • 80 vues
The submitted ticket was accepted; the game session is open.
Kind event · Area Game.Connection
Answers IdentificationRequest on success. Carries no payload - arrival is the whole message.
In a capture it opens a burst delivered in the same millisecond: TimeEvent, ServerSettingsEvent, OptionalFeaturesEvent, AccountCapabilitiesEvent, AccountRightsEvent, TrustStatusEvent and ServerSessionReadyEvent. Do not treat any of those as separately requested; they are pushed.
When you may send it
Requires transport_established observed Related messages
You must then send CharacterListRequest proven — the handler of this event constructs the list request unpopulated and hands it to the network service; without it you never learn which characters exist Arrives after IdentificationRequest No fields you may set.
  • summary: The submitted ticket was accepted; the game session is open.
  • area: Game.Connection
  • 120 vues
The submitted ticket was rejected; the game session does not open.
Kind event · Area Game.Connection
Answers IdentificationRequest on failure. Carries no reason - refusal is the whole message, so there is nothing to branch on beyond the fact of it.
The usual causes are a ticket that was already consumed, has expired, or was issued for a different server than the one you connected to. Recovering means going back to the login-server exchange for a fresh ticket, not retrying this message.
When you may send it
Requires transport_established observed Related messages
Arrives after IdentificationRequest
  • summary: The submitted ticket was rejected; the game session does not open.
  • area: Game.Connection
  • 70 vues
A fresh API key for the in-client shop back end, answering the token request.
Kind event · Area Game.Bak
The reply to BakApiTokenRequest. NEVER PUSHED UNSOLICITED: no request, no key.
Its arrival drives the client's whole key lifecycle. On receiving it the service stores the key, CLEARS the in-flight latch that the send routine set - releasing the next request - and arms a one-hour timer for the next refresh.
If you reproduce the request's timer, reproduce this side too: without clearing the latch on arrival, a faithful implementation sends once and never again.
The key itself is only useful for the shop back end. Nothing in the game protocol is gated on it.
When you may send it
Requires authenticated observed Related messages
Arrives after BakApiTokenRequest Fields
#FieldTypeMeaningYou set it 1api_keystringThe shop back end's API key.
The only member the client reads.
Name ours: no build names this field (the type-name table names types only).never
  • summary: A fresh API key for the in-client shop back end, answering the token request.
  • area: Game.Bak
  • 73 vues
A shop token for the in-client shop back end. In practice it never arrives.
Kind event · Area Game.Bak
IN PRACTICE THIS NEVER ARRIVES, AND THAT IS THE MOST USEFUL THING TO KNOW ABOUT IT.
The shop-token request that would provoke it has NO CLIENT WRITER in any dumped build: the message type exists, but nothing in the client ever constructs or sends it. Since this event is a reply and the client never asks, the server has no occasion to send it. A live capture bears that out - the sibling BakApiKeyEvent appears, this one never does.
DO NOT SEND THE SHOP-TOKEN REQUEST TO PROVOKE IT. No dumped client does, so doing it is a behaviour no real client produces.
The record is here so that its silence is documented rather than mistaken for a gap in the catalogue.
When you may send it
Requires authenticated observed Related messages
Unsolicited - nothing you send causes this nothing in any dumped client asks for it, and a live capture never shows it Fields
#FieldTypeMeaningYou set it 1shop_tokenstringThe shop token.
The only member the client reads. Never populated in a real session.
Name ours: no build names this field (the type-name table names types only).never
  • summary: A shop token for the in-client shop back end. In practice it never arrives.
  • area: Game.Bak
  • 69 vues
Empty server poll asking the client to report its measured latency.
Kind event · Area Game.Basic
Carries no payload - the message IS the question. Answer it with BasicLatencyStatsRequest carrying a latency in milliseconds.
ANSWER IT. A capture shows the real client replying within milliseconds. A client that receives these polls and never answers is trivially distinguishable from a real one.
It arrives in the same frame as SequenceNumberEvent, and the two are answered independently a few milliseconds apart. Report a value consistent with your actual round trips - a real client derives it from its PingRequest / PongEvent samples, and the server can compare what you claim against how long you took to answer.
When you may send it
Requires authenticated observed Related messages
You must then send BasicLatencyStatsRequest observed — the poll is unanswered until the client reports a latency Unsolicited - nothing you send causes this the server polls on its own schedule; nothing you send asks for it Sequence
Step server_poll.2 observed — the server emits both polls in the same frame; of 2 observations
  • summary: Empty server poll asking the client to report its measured latency.
  • area: Game.Basic
  • 75 vues
Where a sub-entity hangs off its parent look: pet, rider, carried entity, or decoration.
Kind enum · Area Game.Common
The category member of SubEntityInformation. It is what tells a mount's rider apart from a pet apart from a carried entity, which is the only part of the look tree most scripts care about.
NOTE THE GAP: value 5 is not declared. The numbering runs 0-4, then 6 and 7. Treat an unknown number as unhandled rather than mapping it onto a neighbour.
Not sent on its own — an enum is never sent on its own. inferred
Used by
SubEntityInformation Values
ValueNumberMeaning HOOK_POINT_CATEGORY_UNUSED0Placeholder for an unset binding point. HOOK_POINT_CATEGORY_PET1A pet following its owner. HOOK_POINT_CATEGORY_MOUNT_DRIVER2The rider sitting on a mount. HOOK_POINT_CATEGORY_LIFTED_ENTITY3An entity being carried by another. HOOK_POINT_CATEGORY_BASE_BACKGROUND4Decoration drawn behind the entity. HOOK_POINT_CATEGORY_BASE_FOREGROUND6Decoration drawn in front of the entity. HOOK_POINT_CATEGORY_UNDERWATER_BUBBLES7The bubble effect used underwater.
  • summary: Where a sub-entity hangs off its parent look: pet, rider, carried entity, or decoration.
  • area: Game.Common
  • 69 vues
One active bonus: an amount and the kind of bonus it applies to.
Kind struct · Area Game.Bonus
A single entry of BonusesEvent. It is never sent on its own.
An entry pairs an AMOUNT with a KIND. Several entries may carry the same kind and they stack, so group them by kind rather than assuming one entry per kind - a captured trace carried five entries sharing a single kind.
The kind's VALUES are deliberately left unnamed; see the signature notes.
Not sent on its own — it is only ever a row of BonusesEvent.bonuses. proven
Used by
BonusesEvent Fields
#FieldTypeMeaningYou set it 1amountint32How much this bonus grants. Several entries may share one kind and stack.never
  • summary: One active bonus: an amount and the kind of bonus it applies to.
  • area: Game.Bonus
  • 70 vues
Every bonus currently in force, as a full replacement list.
Kind event · Area Game.Bonus
This name is not Ankama's. It was chosen for this documentation from proven client behaviour, and is a label rather than protocol documentation.
THE COMPLETE SET, EVERY TIME. Overwrite your bonus state with this list rather than merging into it - the client throws its cache away and rebuilds it from scratch on every arrival.
WHAT A BONUS IS
Each entry is an amount plus the kind of bonus it applies to: extra job experience, extra mount experience, extra quest kamas, and so on. Several entries may share one kind, and they stack - a captured trace carried five separate entries for a single kind. So the useful shape is kind -> list of amounts, which is exactly what the client builds.
WHEN IT ARRIVES
Unprompted, once the game context is up. There is no request for it. It arrives again whenever the server changes what is active, and each arrival replaces the previous set.
READING THE KIND
The kind is an enumeration the client keys its cache by. Its VALUES are not named here: see the signature notes for why the obvious client-side mapping is not proven. Treat an unfamiliar kind as data you do not display, not as an error.
When you may send it
Requires context_ready observed Related messages
Unsolicited - nothing you send causes this no client code builds it; the bonus service only ever receives it Fields
#FieldTypeMeaningYou set it 1bonusesrepeated BonusEvery bonus currently active. A replacement, not a delta.never
  • summary: Every bonus currently in force, as a full replacement list.
  • area: Game.Bonus
  • 75 vues
Whether the account may create another character: allowed, out of slots, or refused.
Kind enum · Area Game.Account
This name is not Ankama's. It was chosen for this documentation from proven client behaviour, and is a label rather than protocol documentation.
THE THREE MEANINGS ARE PROVEN; THE THREE NAMES ARE OURS. The client copies this value unchanged into a player-service property, and the character-selection screen is its only consumer. That screen branches exactly three ways, which is what fixes the meanings:
0 the create button is enabled and its click handler attached 1 the button is disabled with a "buy more slots" tooltip 2 the button is disabled with no such offer VALUE 1 IS A REFUSAL, NOT A YES. This field was a BOOL on earlier builds, so code carried across reads 1 as true and offers character creation that the server will decline. See AccountCapabilitiesEvent.
Not sent on its own — an enum is never sent on its own. inferred
Used by
AccountCapabilitiesEvent Values
ValueNumberMeaning ALLOWED0Character creation is permitted.
WE CHOSE THIS NAME. Proven: the only value for which the client enables the create button. TOO_MANY_CHARACTERS1Refused because the account's slots are full, with more available to buy.
WE CHOSE THIS NAME. Proven: the branch that disables the button and offers more slots. REFUSED2Refused for a reason the client does not spell out.
WE CHOSE THIS NAME. Proven: the client's else branch - disabled, with no offer.
  • summary: Whether the account may create another character: allowed, out of slots, or refused.
  • area: Game.Account
  • 70 vues
Which chat channel a line belongs to, from global and party through to the cross-server community channels.
Kind enum · Area Game.Chat
The channel identifier used by every chat message and by the subscription messages.
ZERO IS GLOBAL, NOT "UNSPECIFIED". This enum has no unspecified member, and the chat messages carry it without explicit presence - so an unset channel field reads as GLOBAL, the loudest channel in the game. Always set it deliberately.
TWO VALUES THE SERVER MAY STILL SEND ARE NO LONGER MAPPED BY THE CLIENT: NOOB and ADS. The client's normalisation switch falls through on them and yields no channel at all. They are kept here because the server can still put them on the wire; handle them as "unknown channel", not as an error.
THREE MORE WIRE VALUES - 17, 18 and 19 - resolve to internal ids the client's readable enum does not name. Two of them are named here from in-game confirmation; the third is our own invention. See TUMULT.
The value names are proven rather than assumed: each wire value was followed through the client's normalisation switch to an internal channel bit, and that bit through the chat metadata table to an unobfuscated name. That chain produces some non-obvious results - wire 9 is ARENA, 10 is PRIVATE, 12 is INFO, 13 is FIGHT_LOG - which is exactly why they are not read off the declaration order.
Not sent on its own — an enum is never sent on its own. inferred
Used by
ChannelUpdateEvent ChatChannelMessageEvent ChatChannelMessageRequest ChatChannelsEnabledEvent SubscribeMultipleChannelRequest Values
ValueNumberMeaning GLOBAL0Open channel visible to everyone nearby. Also the value an unset channel field reads as. TEAM1Team channel. GUILD2Guild channel. ALLIANCE3Alliance channel. PARTY4Party channel. SALES5Trade channel used to advertise goods for sale. SEEK6Recruitment channel used to look for players or groups. NOOB7Newcomer channel.
THE CURRENT CLIENT NO LONGER MAPS THIS VALUE - its normalisation switch falls through with a warning and yields no channel. The server may still send it. ADMIN8Moderation channel reserved for staff. ARENA9Arena channel.
Wire value 9, which the declaration order does not suggest. PRIVATE10Direct messages between two players.
Wire value 10. COMMUNITY11Community channel - the language-segregated public channel.
Added after the reference build; the name comes from the client's own readable chat-channel metadata enum.
Which community you are on is set by SetCommunityChannelRequest.
Name ours, taken from the client's own chat-channel enum: no protocol source names this value. INFO12Informational notices from the server.
Wire value 12. FIGHT_LOG13Combat log channel.
Wire value 13. ADS14Advertisement channel.
THE CURRENT CLIENT NO LONGER MAPS THIS VALUE, the same as NOOB. The server may still send it. EVENT15Event announcements. EXCHANGE16Exchange channel. TUMULT17Wire value 17, whose meaning is not attested by any oracle.
WE CHOSE THIS NAME. No oracle carries an identifier for value 17.
Do not rely on the spelling; the NUMBER is the contract. TERRITORY18Territory channel.
Confirmed in game on 3.6.10.10. Absent before 3.5.3.1 - the value did not exist in the older builds.
Name ours, taken from the client's own chat-channel enum: no protocol source names this value. GUILD_RAID19Guild raid channel.
Confirmed in game on 3.6.10.10. The newest member of the enum, absent from every earlier build.
Name ours, taken from the client's own chat-channel enum: no protocol source names this value.
  • summary: Which chat channel a line belongs to, from global and party through to the cross-server community channels.
  • area: Game.Chat
  • 101 vues
One chat channel was enabled or disabled for the player.
Kind event · Area Game.Chat
The single-channel delta: set that channel's bit when enable is true, clear it when false. Nothing else in the payload is used by the client.
It arrives both on its own and as part of the volley that follows a community change - see SetCommunityChannelRequest.
Keep one channel mask and apply this to it. The bulk counterpart is ChatChannelsEnabledEvent, and the two can disagree if you apply them out of order - the later message wins.
When you may send it
Requires character_loaded observed Related messages
Unsolicited - nothing you send causes this the server toggles channels as availability changes Fields
#FieldTypeMeaningYou set it 2channelChannelThe channel whose state changed.
A Channel value.never 3enableboolTrue when the channel becomes available, false when it is withdrawn.never
  • summary: One chat channel was enabled or disabled for the player.
  • area: Game.Chat
  • 70 vues
One character on the account, as offered in the selection list.
Kind struct · Area Game.Character.Management
One selectable character. It is what you read to decide which CharacterSelectionRequest to send, and id is the value that request wants.
THE INTERESTING PARTS ARE NESTED, NOT FLAT. The name, level and appearance are one level down in CharacterBasicInformation, and the appearance one further down again in CharacterInformation. Do not expect a flat record.
character_remodeling_information is an ALTERNATIVE representation used while a character is being remodelled - it is the other branch of the same oneof as the basic information. Branch on which one is set: a remodelling character has no basic information to read.
Members beyond the ones named here exist and stand with their obfuscated names. They are not decoys - they are simply not proven yet, so do not read meaning into their position.
Not sent on its own — it is only ever an element of CharacterListEvent. inferred
Used by
CharacterListEvent CharacterSelectionEvent.Success PartyJoinEvent PartyMemberUpdateEvent PartyNewMemberEvent Fields
#FieldTypeMeaningYou set it 3idint64The character id, and the value CharacterSelectionRequest addresses it by. (character id)never 2character_remodeling_informationCharacterRemodelingInformationThe alternative representation used while the character is being remodelled.
The other branch of the same oneof as the basic information.
See CharacterRemodelingInformation.never 4character_basic_informationCharacterBasicInformationThe character's name, level and appearance.
See CharacterBasicInformation. One branch of a oneof - check it is the one that is set.never
  • summary: One character on the account, as offered in the selection list.
  • area: Game.Character.Management
  • 89 vues
The colour palettes your character owns, and how many palette slots exist.
Kind event · Area Game.Cosmetic
YOUR COLLECTION OF COLOUR PALETTES. Each palette is a set of six colours you can apply to your character; this message lists the ones you own and states how many palette slots your account has.
WHEN IT ARRIVES
Unprompted, once the game context is up, and again whenever the collection changes. Treat it as a REPLACEMENT: the client discards its previous list and rebuilds it from what arrives.
READING A PALETTE
A palette is six packed RGB integers - 8025436 is 0x7A75DC. A palette entry may legitimately be short or empty, in which case the missing colours fall back to your breed's defaults; the client does exactly that, looking the breed up in its game data before filling the gaps. So do not assume six values are always present.
WHAT IT NO LONGER CARRIES
Up to 3.5.3.1 this message also carried the character's FACES collection alongside the colours. From 3.5.17.26 on it carries colours only. If you are reading an older capture, expect the extra member.
When you may send it
Requires context_ready observed Related messages
Unsolicited - nothing you send causes this no client code builds it; the inventory service only ever receives it Fields
#FieldTypeMeaningYou set it 2colorsCharacterColorsThe palettes you own, with the slot counts that bound them.never
  • summary: The colour palettes your character owns, and how many palette slots exist.
  • area: Game.Cosmetic
  • 90 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.