# Mapa de Opcodes do Protocolo (Karos/Rosh Online)

Extraído automaticamente do `AMo.exe` em 22/08 pelo script
`D:\Cabal\Tools\ghidra_projects\MapOpcodes0822.java`.

## Como foi obtido (reproduzível)

O binário tem RTTI habilitado: cada classe de pacote deixa uma string
`.?AVC<Nome>Packet@AMOPacket@@`. A partir dela dá pra chegar no opcode sem adivinhação:

1. `type_info` fica 8 bytes antes da string RTTI
2. procurar um ponteiro para esse `type_info` -> é o campo `pTypeDescriptor` do
   `CompleteObjectLocator` (offset 12 da struct)
3. procurar um ponteiro para o início do COL -> ele fica em `vtable - 4`
4. `vtable[1]` é o método `Parse` da classe
5. o `Parse` começa comparando os 2 bytes do opcode
   (`CMP byte ptr [reg], imm` / `CMP byte ptr [reg+1], imm`) -> esses são os bytes

O script indexa a memória inteira uma vez (500k valores) em vez de fazer uma busca por
classe, senão levaria minutos.

**Resultado: 94 opcodes mapeados de 349 classes de pacote.** As que faltam ou não têm
vtable resolvível sem análise completa, ou fazem a checagem de opcode de outra forma.

## Famílias

| prefixo | qtd | assunto |
|---|---|---|
| `03` | 29 | comunidade (chat, party, guild, amigos) |
| `06` | 20 | itens / inventário |
| `02` | 13 | login / seleção de personagem / canal |
| `0c` | 9 | (a classificar) |
| `04` | 9 | **movimento e entidades** |
| `05` | 5 | combate |
| `08` | 4 | status do personagem (HP/MP/gauges) |

## Família 04 — movimento e entidades (96% do tráfego do mundo)

Estes três respondem por quase todo o fluxo contínuo que o servidor real manda:

| opcode | classe | % do stream | tamanho |
|---|---|---|---|
| `04 01` | `CMoveMovePacket` | 73.5% | 42 bytes fixos |
| `04 02` | `CMoveAppearPacket` | 11.4% | 260-266 bytes |
| `04 03` | `CMoveDisappearPacket` | 10.9% | 11 bytes fixos |

Demais da família:

| opcode | classe |
|---|---|
| `04 00` | `CMoveRegenPacket` (é o que o CLIENT manda ao andar -- confirmado no log) |
| `04 04` | `CMoveZonePacket` |
| `04 05` | `CMoveWarpreqPacket` |
| `04 06` | `CMoveWarpgatePacket` |
| `04 07` | `CMoveWarpPacket` |
| `04 08` | `CMoveGMSummonAppearPacket` |

### Por que isso importa pro problema da desconexão

O client cai ~14s depois de entrar no mundo porque o `world_server.py` só reproduz um
trecho gravado finito. Agora sabemos que esse fluxo é 96% spawn/move/despawn de **outras
entidades** -- e que os IDs de entidade nesses pacotes vêm de uma sessão alheia (por isso
reproduzir o gravado em loop piora, conforme já testado). O caminho correto é **gerar**
`CMoveAppearPacket`/`CMoveMovePacket` com IDs próprios, em vez de reproduzir bytes de outra
sessão.

## Tabela completa

```
01 13   CFailPacket                                  parse@00451469
02 00   CLoginReqPacket                              parse@00650f15
02 01   CLoginCharViewInfoPacket                     parse@00650aac
02 02   CLoginCreateCharPacket                       parse@00647f67
02 03   CLoginDeleteCharPacket                       parse@006506ec
02 04   CLoginStartCharPacket                        parse@005ab98b
02 05   CLoginCharInfoPacket                         parse@00650710
02 06   CChannelWaitLoginPacket                      parse@0065081f
02 06   CLoginChannelListPacket                      parse@0065083b
02 07   CLoginChannelChangePacket                    parse@006507ba
02 08   CLoginSecondPasswdRegisterPacket             parse@0064810f
02 09   CLoginSecondPasswdRevisionPacket             parse@006481d2
02 0a   CLoginSecondPasswdDeletePacket               parse@00648295
02 0b   CLoginSecondPasswdCheckPacket                parse@00648358
03 00   CCommunityChatPacket                         parse@0056ad7e
03 01   CCommunityWhisperPacket                      parse@0064bca1
03 02   CCommunityActionPacket                       parse@00649642
03 08   CCommunityTotalPacket                        parse@0064be30
03 0a   CArenaMatchBreakAwayPacket                   parse@006496ce
03 0a   CArenaMatchCancelPacket                      parse@006496a3
03 0a   CArenaMatchMemberSurvivalCountPacket         parse@006496a3
03 0a   CArenaMatchWaitListRegisterPacket            parse@006496a3
03 0a   CAttackDetectPacket                          parse@006496a3
03 0a   CCharInfoHelpHuntActionSettingPacket         parse@006496a3
03 0a   CCommunityBoardingPacket                     parse@006496ce
03 0a   CCommunityPartyItemPickupPacket              parse@006496f4
03 0a   CCommunityPartyLootingPacket                 parse@006496a3
03 0a   CCommunityPartyOutPacket                     parse@006496ce
03 0a   CCommunityPartyThrowPacket                   parse@006496ce
03 0a   CEventInformProgressPacket                   parse@006496ce
03 0a   CEventPushTriggerPacket                      parse@006496a3
03 0a   CGuildAutoRejectInfoPacket                   parse@006496a3
03 0a   CItemPersonalTradeCheckPacket                parse@006496ce
03 0a   CItemPersonalTradeCompletePacket             parse@006496ce
03 0a   CItemQuickSlotDelPacket                      parse@006496a3
03 0a   CItemSelfShopSellArticleCancelPacket         parse@006496ce
03 0a   CItemSelfShopSellArticleRegisterStopPacket   parse@006496ce
03 0a   COccupationWarProgressPacket                 parse@006496a3
03 0a   CQuestListPacket                             parse@006496ce
03 0a   CRVRRPPointGetPacket                         parse@006496a3
03 0b   CCommunityPartyMemberMovePacket              parse@0064971f
03 16   CCommunityBoardingInfoPacket                 parse@00649a08
03 16   CItemMoveAllMailPacket                       parse@00649992
04 00   CMoveRegenPacket                             parse@0065f33e
04 01   CMoveMovePacket                              parse@0065f36f
04 02   CMoveAppearPacket                            parse@00666d0f
04 03   CMoveDisappearPacket                         parse@0065f3ad
04 04   CMoveZonePacket                              parse@005f4853
04 05   CMoveWarpreqPacket                           parse@006470f2
04 06   CMoveWarpgatePacket                          parse@0065f3de
04 07   CMoveWarpPacket                              parse@0065f40f
04 08   CMoveGMSummonAppearPacket                    parse@006470d4
05 00   CAttackStartPacket                           parse@0065f440
05 01   CAttackDecidePacket                          parse@00647116
05 02   CAttackDamagePacket                          parse@0065f471
05 03   CAttackSkillReadyPacket                      parse@0065f4a2
05 0a   CCoolTimeSkillListPacket                     parse@0065f59a
06 00   CItemWearPacket                              parse@0061da63
06 01   CItemPutoffPacket                            parse@0061da94
06 02   CItemUsePacket                               parse@005f5c79
06 03   CItemPickupPacket                            parse@0063b7d8
06 04   CItemDropPacket                              parse@00651fda
06 05   CItemInvenListPacket                         parse@00652005
06 06   CItemInvenPutinPacket                        parse@00652050
06 07   CItemInvenPutoutPacket                       parse@0061dac5
06 08   CItemInvenSwapPacket                         parse@0061daf6
06 2c   CItemStashSwapPacket                         parse@00652171
06 2d   CItemAccountStashSwapPacket                  parse@006521a2
06 2e   CItemStashOpenLevelListPacket                parse@00652113
06 2f   CCoolTimeListPacket                          parse@006520b5
06 32   CItemCashShopBuyPacket                       parse@00652297
06 32   CItemCashShopItemUsePacket                   parse@006522bd
06 3c   CItemRepurchaserBuyPacket                    parse@00652223
06 3c   CLimitCashShopListPacket                     parse@0065225a
06 3f   CItemPCCombinationPacket                     parse@00652084
06 53   CBannerCashShopListPacket                    parse@00648478
06 57   CItemRepurItemListPacket                     parse@006521dc
08 00   CCharInfoGagePacket                          parse@0065f5ce
08 01   CCharInfoHeroGagePacket                      parse@0065f5ff
08 06   CCharInfoGageCurHPMPPacket                   parse@0065f630
08 11   CCharInfoPacket                              parse@006507eb
0b 01   CSystemNoticePacket                          parse@00646420
0c 12   CGuildStashListPacket                        parse@00652568
0c 12   CGuildStashPutinPacket                       parse@00652510
0c 12   CGuildStashSwapPacket                        parse@006525a0
0c 12   CItemAccountStashListPacket                  parse@00652568
0c 12   CItemAccountStashPutinPacket                 parse@00652510
0c 12   CItemCombAttrPacket                          parse@00652510
0c 12   CItemMixedReinforcePacket                    parse@00652510
0c 12   CItemStashListPacket                         parse@00652568
0c 12   CItemStashPutinPacket                        parse@00652510
0e 1b   CFatiguePacket                               parse@00647306
0e 1b   CShutdownPacket                              parse@00647306
14 0e   CArenaMatchControlPacket                     parse@006472ab
```
