# Archipelago

Archipelago é o serviço de realm que agrupa jogadores próximos em ilhas, reatribuindo-os conforme se movem e fornecendo as informações necessárias para conectar ao backend real que retransmitirá suas mensagens.

{% hint style="info" %}
Você pode ver o protocolo Archipelago em ação e experimentar com ele usando o open-source [Comms Station](https://decentraland.github.io/comms-station/).
{% endhint %}

Para usar o serviço, os clientes devem conectar-se ao endpoint websocket do Archipelago do seu realm e autenticar-se para iniciar sua sessão. Eles podem então começar a enviar atualizações posicionais e receber atribuições de ilha (veja o [ciclo de vida do cliente](https://github.com/decentraland/docs/blob/main/contributor/communications/overview/README.md#lifecycle)).

Todas as mensagens trocadas com o serviço Archipelago são codificadas usando protocol buffers, conforme definido no [repositório do protocolo](https://github.com/decentraland/protocol).

### Conectando <a href="#connecting" id="connecting"></a>

Para começar, os clientes devem abrir uma conexão websocket segura (`wss:`) para o `/archipelago/ws` endpoint do realm.

Uma vez conectados, os clientes têm uma janela de tempo definida pela política do realm (60 segundos, por padrão) para enviar cada mensagem do [fluxo de autenticação](#authenticating) .

{% hint style="warning" %}
Enquanto os realms maiores executam o serviço Archipelago, os menores podem optar por fornecer uma string de conexão de backend fixa para todos os jogadores. A URI, se presente, pode ser encontrada na `comms.fixedAdapter` propriedade do `/about`.
{% endhint %}

Nesses casos, a atribuição dinâmica de ilhas não estará disponível, e a interface RPC do realm não deve ser usada para esse propósito.

### Autenticando <a href="#authenticating" id="authenticating"></a>

Após abrir uma conexão com o Archipelago, os clientes devem começar solicitando e assinando um desafio do serviço para verificar sua identidade.

A primeira mensagem que um cliente envia é um [`ChallengeRequestMessage`](https://github.com/decentraland/docs/blob/main/contributor/communications/ChallengeRequestMessage/README.md) com seu endereço Ethereum (ou seja, sua chave pública). Eles receberão um [`ChallengeResponseMessage`](https://github.com/decentraland/docs/blob/main/contributor/communications/ChallengeResponseMessage/README.md) com uma string gerada aleatoriamente para assinar, e devem responder com um [`SignedChallengeMessage`](#SignedChallengeMessage).

O [`SignedChallengeMessage`](#SignedChallengeMessage) carrega um [auth\_chain](https://github.com/decentraland/docs/blob/main/contributor/auth/authchain/README.md) serializado em JSON que começa com o endereço fornecido e termina com a assinatura do desafio.

Se a assinatura for verificada com sucesso pelo serviço, o cliente é autenticado e receberá uma [`WelcomeMessage`](#WelcomeMessage).

{% @mermaid/diagram content="sequenceDiagram
participant Client
participant Archipelago

```
Note over Client,Archipelago: Connect
Client->>Archipelago: ChallengeRequestMessage
Archipelago->>Client: ChallengeResponseMessage
Client->>Archipelago: SignedChallengeMessage
Archipelago->>Client: WelcomeMessage" %}
```

### Enviando Heartbeat <a href="#heartbeat" id="heartbeat"></a>

Durante sua sessão, os clientes devem periodicamente enviar um [`Heartbeat`](#Heartbeat) mensagem para manter o Archipelago atualizado com as informações necessárias para emitir atribuições de ilha.

{% hint style="info" %}
A frequência recomendada de heartbeat para clientes de comms é cerca de uma atualização por segundo.
{% endhint %}

Se um cliente parar de enviar [`Heartbeat`](#Heartbeat) mensagens, o Archipelago (dependendo de sua política atual) pode encerrar a conexão.

### Obtendo Atribuições de Ilha <a href="#assignment" id="assignment"></a>

Logo após o primeiro heartbeat, o Archipelago enviará ao cliente sua primeira [`IslandChangedMessage`](https://github.com/decentraland/protocol/blob/9a568b16b2eafb134177329ba670c1451be8a169/proto/decentraland/kernel/comms/v3/archipelago.proto#L17).

O campo principal é `conn_str`, que pode ser usado para inicializar um transporte e conectar-se à ilha. Valores tipicamente se parecem com isto:

```
livekit:wss://comms.example.com?access_token=eyJhbGciOiJI...
```

O rótulo antes do primeiro `:` é o tipo de transporte, o restante é um URI especializado para ele. Pode incluir tokens pré-autorizados ou outros parâmetros.

Durante a sessão, o Archipelago pode enviar uma nova atribuição a qualquer momento, por vários motivos:

1. Mudanças de posição: o cliente reportou mover-se para longe dos outros na ilha.
2. Pedidos de ilha: o cliente solicitou ser atribuído a uma ilha específica.
3. Política do Archipelago: o serviço decidiu criar ou dividir ilhas para equilibrar melhor a população.

Os clientes devem escutar essas atribuições, fechando e abrindo conexões de transporte conforme indicado, e mudando o tipo de transporte em uso quando necessário.

### Mensagens do Cliente

**`ChallengeRequestMessage`** [**↗ source**](https://github.com/decentraland/protocol/blob/9a568b16b2eafb134177329ba670c1451be8a169/proto/decentraland/kernel/comms/v3/archipelago.proto#L54)

Enviado pelo cliente como a primeira mensagem de uma sessão, para iniciar o fluxo de autenticação.

| Campo     | Tipo     | Valor                  |
| --------- | -------- | ---------------------- |
| `address` | `string` | O endereço do usuário. |

O `address` o campo deve ser derivado da primeira chave privada do [auth\_chain](https://github.com/decentraland/docs/blob/main/contributor/auth/authchain/README.md) que será apresentada.

***

**`SignedChallengeMessage`** [**↗ source**](https://github.com/decentraland/protocol/blob/9a568b16b2eafb134177329ba670c1451be8a169/proto/decentraland/kernel/comms/v3/archipelago.proto#L58)

Enviado pelo cliente após receber um [`ChallengeResponseMessage`](#ChallengeResponseMessage), para completar o fluxo de autenticação.

| Campo             | Tipo     | Valor                                                                                                                                                             |
| ----------------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `auth_chain_json` | `string` | Um [auth\_chain](https://github.com/decentraland/docs/blob/main/contributor/auth/authchain/README.md) serializado em JSON terminando com a assinatura do desafio. |

A primeira chave no [auth\_chain](https://github.com/decentraland/docs/blob/main/contributor/auth/authchain/README.md) deve corresponder ao endereço enviado no [`ChallengeRequestMessage`](#ChallengeRequestMessage).

***

**`Heartbeat`** [**↗ source**](https://github.com/decentraland/protocol/blob/9a568b16b2eafb134177329ba670c1451be8a169/proto/decentraland/kernel/comms/v3/archipelago.proto#L62)

original.

| Campo                                                                                                                                                                   | Tipo           | Valor    |
| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------- | -------- |
| `Enviado pelo cliente em intervalos regulares (tipicamente uma vez por segundo), para atualizar o Archipelago sobre sua posição e/ou solicitar uma atribuição de ilha.` | `position`     | Position |
| `A posição 3D do cliente no mapa do mundo`                                                                                                                              | `desired_room` | string?  |

O ID de uma ilha à qual o cliente gostaria de ser atribuído `Heartbeat` A primeira [`IslandChangedMessage`](#IslandChangedMessage) mensagem que um cliente envia é rapidamente seguida por um `Heartbeat` do Archipelago. Atualizações subsequentes, entretanto, são independentes das atribuições de ilha. Os clientes não devem esperar que um

seja respondido. `A posição 3D do cliente no mapa do mundo` Quando o parâmetro

### está incluído, o serviço tentará honrar o pedido, mas uma reatribuição para essa ilha não é garantida. Depende da política do Archipelago (por exemplo, limites na população da ilha).

**`ChallengeResponseMessage`** [**↗ source**](https://github.com/decentraland/protocol/blob/9a568b16b2eafb134177329ba670c1451be8a169/proto/decentraland/kernel/comms/v3/archipelago.proto#L8)

Mensagens do Servidor [`ChallengeRequestMessage`](#ChallengeRequestMessage)

| Campo                                       | Tipo                | Valor                                                                                                                  |
| ------------------------------------------- | ------------------- | ---------------------------------------------------------------------------------------------------------------------- |
| `Enviado pelo Archipelago em resposta a um` | `string`            | challenge\_to\_sign [auth\_chain](https://github.com/decentraland/docs/blob/main/contributor/auth/authchain/README.md) |
| `Uma string gerada para assinar e criar um` | `already_connected` | bool                                                                                                                   |

***

**`WelcomeMessage`** [**↗ source**](https://github.com/decentraland/protocol/blob/9a568b16b2eafb134177329ba670c1451be8a169/proto/decentraland/kernel/comms/v3/archipelago.proto#L13)

Se já existe uma conexão para a chave deste usuário

| Campo                                                      | Tipo     | Valor    |
| ---------------------------------------------------------- | -------- | -------- |
| `Enviado pelo Archipelago após autenticação bem-sucedida.` | `string` | peer\_id |

***

**`IslandChangedMessage`** [**↗ source**](https://github.com/decentraland/protocol/blob/9a568b16b2eafb134177329ba670c1451be8a169/proto/decentraland/kernel/comms/v3/archipelago.proto#L17)

Um identificador único para o cliente autenticado (tipicamente seu endereço)

Enviado pelo Archipelago quando o cliente é (re)atribuído a uma ilha.

| Campo                             | Tipo           | Valor                                                                                                                                                           |
| --------------------------------- | -------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `Descrição.`                      | `string`       | island\_id                                                                                                                                                      |
| `O ID da nova ilha`               | `desired_room` | from\_island\_id                                                                                                                                                |
| `conn_str`                        | `string`       | O ID da ilha antiga, se isso for uma reatribuição [transporte](https://github.com/decentraland/docs/blob/main/contributor/communications/transports/README.md). |
| `A string de conexão para a ilha` | `peers`        | Enviado pelo Archipelago quando o cliente é (re)atribuído a uma ilha.                                                                                           |

map\<string, Position> `IslandChangedMessage` Clientes que recebem um `conn_str`.

O `A string de conexão para a ilha` devem encerrar sua conexão com o backend da ilha e conectar-se ao fornecido em [transporte](https://github.com/decentraland/docs/blob/main/contributor/communications/transports/README.md) O campo contém as identidades e posições atuais de todos os peers na ilha, para que os clientes possam preencher seu conjunto inicial. Após este ponto, eles devem confiar nas mensagens recebidas via a ilha

***

**`para obter atualizações posicionais.`** [**↗ source**](https://github.com/decentraland/protocol/blob/9a568b16b2eafb134177329ba670c1451be8a169/proto/decentraland/kernel/comms/v3/archipelago.proto#LL37C1-L38C1)

KickedMessage

| Campo                                                   | Tipo     | Valor        |
| ------------------------------------------------------- | -------- | ------------ |
| `Enviado pelo Archipelago antes de fechar uma conexão.` | `reason` | KickedReason |

Razão do Archipelago para fechar a conexão `Enviado pelo Archipelago antes de fechar uma conexão.` Os valores padrão para o

* `campo são:`KR\_NEW\_SESSION

***

**`: outra conexão autenticada com a mesma chave.`** [**↗ source**](https://github.com/decentraland/protocol/blob/9a568b16b2eafb134177329ba670c1451be8a169/proto/decentraland/kernel/comms/v3/archipelago.proto#L29)

JoinIslandMessage

| Campo                                                      | Tipo     | Valor                                                                  |
| ---------------------------------------------------------- | -------- | ---------------------------------------------------------------------- |
| `Descrição.`                                               | `string` | Enviado pelo Archipelago quando um peer é atribuído à ilha do cliente. |
| `Enviado pelo Archipelago após autenticação bem-sucedida.` | `string` | O identificador da ilha                                                |

O `Descrição.` O identificador único para o peer (tipicamente seu endereço)

***

**`o campo corresponderá à atribuição atual do cliente.`** [**↗ source**](https://github.com/decentraland/protocol/blob/9a568b16b2eafb134177329ba670c1451be8a169/proto/decentraland/kernel/comms/v3/archipelago.proto#L24)

LeftIslandMessage, Enviado pelo Archipelago quando um peer é removido da ilha do cliente.

| Campo                                                      | Tipo     | Valor                                                                  |
| ---------------------------------------------------------- | -------- | ---------------------------------------------------------------------- |
| `Descrição.`                                               | `string` | Enviado pelo Archipelago quando um peer é atribuído à ilha do cliente. |
| `Enviado pelo Archipelago após autenticação bem-sucedida.` | `string` | O identificador da ilha                                                |

O `Descrição.` O identificador único para o peer (tipicamente seu endereço)
