> For the complete documentation index, see [llms.txt](https://docs.nursultan.fun/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.nursultan.fun/scripting-api-ru/deistviya/pakety.md).

# Пакеты

Пакет — это сообщение между клиентом и сервером. Через пакеты видно то, что не видно иначе: точный момент отбрасывания, системные сообщения, действия других игроков.

## Два потока

Пакеты приходят **не на клиентском потоке**. Читать поля пакета там можно и нужно, а вот трогать мир, игрока или инвентарь — нельзя. Для этого перепрыгни:

```kotlin
on<PacketReceiveEvent> { e ->
    val packet = e.packet()
    if (packet !is S2CEntityVelocityPacket) return@on
    if (packet.entityId() != player.id()) return@on

    onClientThread {
        control.jump()
    }
}
```

Забудешь про `onClientThread` — получишь редкие странные баги, которые тяжело поймать.

## Что приходит

```kotlin
on<PacketReceiveEvent> { e -> e.packet() }   // от сервера, S2CPacket
on<PacketSendEvent> { e -> e.packet() }      // от клиента, C2SPacket
```

Пакеты — это Kotlin-записи, поэтому разбирать их удобнее всего через `when`:

```kotlin
on<PacketReceiveEvent> { e ->
    val text = when (val packet = e.packet()) {
        is S2CGameMessagePacket -> if (packet.overlay()) null else packet.content()
        is S2CProfilelessChatMessagePacket -> packet.message()
        is S2CChatMessagePacket -> packet.unsignedContent()
        else -> null
    }
    if (text != null && text.contains("дуэль")) {
        onClientThread { chat.sendToServer("/next") }
    }
}
```

## Отмена

И входящие, и исходящие пакеты можно отменить:

```kotlin
on<PacketSendEvent> { e ->
    if (e.packet() is C2SClientTickEndPacket) {
        e.cancel()
    }
}
```

Отменяй с осторожностью: сервер ждёт от клиента определённого поведения, и слишком творческий подход заканчивается киком.

## Отправить свой

```kotlin
game.packets().send(C2SChatMessagePacket("привет", 0L, 0L))
game.packets().sendSequenced(C2SPlayerActionPacket(...))
```

`send` возвращает `false`, если отправить не получилось — например, нет подключения.

`sendSequenced` нужен для пакетов, которые сервер нумерует: взаимодействия с блоками и предметами. Если сомневаешься — обычный `send`.

## Как называются пакеты

Имена собраны из ванильных: приставка `C2S` — от клиента к серверу, `S2C` — от сервера к клиенту.

Чаще всего нужны:

| Пакет                                                                             | Про что                 |
| --------------------------------------------------------------------------------- | ----------------------- |
| `S2CEntityVelocityPacket`                                                         | кого-то оттолкнуло      |
| `S2CGameMessagePacket`, `S2CChatMessagePacket`, `S2CProfilelessChatMessagePacket` | сообщения в чате        |
| `S2CEntityDamagePacket`                                                           | кому-то нанесли урон    |
| `S2CEntityStatusEffectPacket`                                                     | кому-то повесили эффект |
| `S2CInventoryPacket`, `S2CScreenHandlerSlotUpdatePacket`                          | обновился инвентарь     |
| `S2CExplosionPacket`                                                              | взрыв                   |
| `S2CEntityPositionPacket`, `S2CEntityMoveRelativePacket`                          | сущность подвинулась    |
| `C2SMoveFullPacket`, `C2SMoveLookPacket`, `C2SMoveOnGroundPacket`                 | наше движение           |
| `C2SChatMessagePacket`, `C2SCommandExecutionPacket`                               | что мы пишем            |
| `C2SPlayerInteractEntityPacket`, `C2SPlayerActionPacket`                          | наши действия           |

Полный список — в автодополнении IDE: набери `S2C` или `C2S` и смотри, что предлагается. Все они уже импортированы, писать `import` не нужно.

## Привязка к версии Minecraft

Пакеты — единственная часть API, привязанная к версии игры. При обновлении Minecraft поля и имена пакетов могут поменяться. Если твой скрипт их использует, распространяй его вместе с подходящей версией клиента и обнови джарку пакетов в `.sdk/`, когда обновляешься сам.

Скрипты, которые пакеты не трогают, обновление Minecraft переживают без правок.
