# Protocol Notes ## Opcode Decoder Map (Client) Source: `hs-client/Assembly-CSharp/ConnectAPI.cs`. - `116` → `PongPacketDecoder` - `169` → `Deadend` - `167` → `DeadendUtil` - `123` → `DebugConsoleCommand` - `124` → `DebugConsoleResponse` - `14` → `AllOptions` - `5` → `DebugMessage` - `17` → `EntityChoices` - `13` → `EntitiesChosen` - `16` → `GameSetup` - `19` → `PowerHistory` - `15` → `UserUI` - `9` → `TurnTimer` - `10` → `NAckOption` - `12` → `GameCanceled` - `23` → `ServerResult` - `24` → `SpectatorNotify` - `289` → `Disconnected` - `202` → `DeckList` - `207` → `Collection` - `215` → `GetDeckContentsResponse` - `216` → `DBAction` - `217` → `DeckCreated` - `218` → `DeckDeleted` - `219` → `DeckRenamed` - `212` → `ProfileNotices` - `224` → `BoosterList` - `226` → `BoosterContent` - `208` → `GamesInfo` - `231` → `ProfileDeckLimit` - `262` → `ArcaneDustBalance` - `278` → `GoldBalance` - `233` → `ProfileProgress` - `270` → `PlayerRecords` - `271` → `RewardProgress` - `232` → `MedalInfo` - `241` → `ClientOptions` - `246` → `DraftBeginning` - `247` → `DraftRetired` - `248` → `DraftChoicesAndContents` - `249` → `DraftChosen` - `288` → `DraftRewardsAcked` - `251` → `DraftError` - `252` → `Achieves` - `285` → `ValidateAchieveResponse` - `282` → `CancelQuestResponse` - `264` → `GuardianVars` - `260` → `CardValues` - `258` → `BoughtSoldCard` - `269` → `MassDisenchantResponse` - `265` → `BattlePayStatusResponse` - `295` → `ThirdPartyPurchaseStatusResponse` - `272` → `PurchaseMethod` - `275` → `CancelPurchaseResponse` - `256` → `PurchaseResponse` - `238` → `BattlePayConfigResponse` - `280` → `PurchaseWithGoldResponse` - `283` → `HeroXP` - `254` → `NoOpPacketDecoder` - `286` → `PlayQueue` - `330` → `CheckAccountLicensesResponse` - `331` → `CheckGameLicensesResponse` - `236` → `CardBacks` - `292` → `SetCardBackResponse` - `296` → `SetProgressResponse` - `299` → `TriggerEventResponse` - `300` → `NotSoMassiveLoginReply` - `304` → `AssetsVersionResponse` - `306` → `AdventureProgressResponse` - `307` → `UpdateLoginComplete` - `311` → `AccountLicenseAchieveResponse` - `315` → `SubscribeResponse` - `316` → `TavernBrawlInfo` - `317` → `TavernBrawlPlayerRecordResponse` - `318` → `FavoriteHeroesResponse` - `320` → `SetFavoriteHeroResponse` - `324` → `DebugCommandResponse` - `325` → `AccountLicensesInfoResponse` - `326` → `GenericResponse` - `328` → `ClientRequestResponse` - `322` → `GetAssetResponse` ## Opcode Encoder Map (Client → Server) Game server outbound (QueueGamePacket): - `22` → `SpectatorHandshake` - `168` → `Handshake` - `1` → `GetGameState` - `115` → `Ping` - `11` → `Concede` - `3` → `ChooseEntities` - `2` → `ChooseOption` - `15` → `UserUI` (emote + mouse) - `25` → `InviteToSpectate` - `26` → `RemoveSpectators` - `123` → `DebugConsoleCommand` Debug console outbound (QueueDebugPacket): - `124` → `DebugConsoleResponse` Util server outbound (ClientRequestManager/UtilOutbound): - `319` → `SetFavoriteHero` - `279` → `PurchaseWithGold` - `312` → `StartThirdPartyPurchase` - `293` → `SubmitThirdPartyReceipt` - `294` → `GetThirdPartyPurchaseStatus` - `250` → `GetPurchaseMethod` - `273` → `DoPurchase` - `274` → `CancelPurchase` - `237` → `GetBattlePayConfig` - `255` → `GetBattlePayStatus` - `268` → `MassDisenchantRequest` - `235` → `DraftBegin` - `242` → `DraftRetire` - `287` → `DraftAckRewards` - `244` → `DraftGetPicksAndContents` - `245` → `DraftMakePick` - `201` → `GetAccountInfo` - `327` → `GenericRequestList` - `205` → `UpdateLogin` - `214` → `GetDeckContents` - `209` → `CreateDeck` - `210` → `DeleteDeck` - `211` → `RenameDeck` - `332` → `DeckSetTemplateSource` - `222` → `DeckSetData` - `213` → `AckNotice` - `225` → `OpenBooster` - `230` → `SetProgress` - `298` → `TriggerLaunchDayEvent` - `303` → `GetAssetsVersion` - `308` → `AckWingProgress` - `309` → `AcknowledgeBanner` - `310` → `SetAdventureOptions` - `223` → `AckCardSeen` - `240` → `GetOptions` - `239` → `SetOptions` - `253` → `GetAchieves` - `284` → `ValidateAchieve` - `281` → `CancelQuest` - `243` → `AckAchieveProgress` - `297` → `CheckAccountLicenseAchieve` - `305` → `GetAdventureProgress` - `257` → `BuySellCard` - `267` → `CheckAccountLicenses` - `276` → `CheckGameLicenses` - `291` → `SetCardBack` - `321` → `GetAssetRequest` - `329` → `Unsubscribe` - `322` → `DebugCommandRequest` ## Learnings - Client maintains deferred response maps for async requests in `Network.cs`. - Opcode map is a key compatibility anchor for the Go gateway. ## Protobuf Definitions (Source) The repo does not contain the protobuf class definitions for most message types. They live in the client assemblies that were not decompiled here. To generate Go structs, extract `.proto` from the client install: - `PegasusGame.dll` (game server packets) - `PegasusUtil.dll` (utility/account/collection packets) - `SpectatorProto.dll` (spectator packets) - `BobNetProto.dll` (misc/legacy) - `PegasusShared.dll` (shared types: `CardDef`, `BnetId`, enums) Suggested mapping (verify by decompiling those DLLs): - `PegasusGame`: `GameSetup`, `PowerHistory`, `EntityChoices`, `EntitiesChosen`, `UserUI`, `TurnTimer`, `NAckOption`, `GameCanceled`, `ServerResult`, `Disconnected`, `Handshake`, `GetGameState`, `Ping`, `Concede`, `ChooseEntities`, `ChooseOption`. - `SpectatorProto`: `SpectatorHandshake`, `SpectatorNotify`, `InviteToSpectate`, `RemoveSpectators`. - `PegasusUtil`: everything in the decoder/encoder maps that relates to collection, login, decks, purchases, achievements, and assets (most of the `UtilOutbound` messages). - `BobNetProto`: `Deadend`, `DeadendUtil` (verify).