> For the complete documentation index, see [llms.txt](https://docs.quickclient.cc/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.quickclient.cc/events/basics.md).

# Подписка на события

Как подписаться на событие, отменить его и прочитать данные.

Скрипт подписывается на события в `activate()`. Подписка действует, пока скрипт включён. При выключении Quick снимает её сам, а при следующем включении `activate()` подписывается заново.

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

```java
@Override
public void activate() {
    on("attack", event -> log().info("удар"));

    on(KeyEvent.class, event -> {
        if (event.pressed() && event.key() == 'F' && !event.screen().open()) {
            chat("нажата F");
        }
    });

    on(ChatEvent.class, event -> {
        if (event.server() && event.contains("присоединился")) event.cancel();
    });
}
```

## Как это работает

* При каждом ударе в консоль пишется строка.
* При нажатии F, если никакой экран не открыт, в чат выводится сообщение.
* Серверные сообщения о входе игроков скрываются.

## Методы

| Метод                            | Тип        | Описание                                                     |
| -------------------------------- | ---------- | ------------------------------------------------------------ |
| `on(eventName, handler)`         | `boolean`  | подписка по имени; `false`, если Quick не знает такого имени |
| `on(EventClass.class, listener)` | `boolean`  | подписка на типизированное событие                           |
| `off(eventName)`                 | `void`     | снять подписки скрипта на одно событие                       |
| `eventNames()`                   | `String[]` | какие имена знает текущая сборка Quick                       |

Обработчик вызывается в главном потоке игры. Если в нём возникает исключение, скрипт выключается, а причина выводится в консоль.

## ScriptEvent

При подписке по имени обработчик получает `ScriptEvent`. Quick использует один и тот же объект для всех вызовов, поэтому сохранять его в поле нельзя: вне обработчика он пустой.

| Метод           | Тип       | Описание                                                              |
| --------------- | --------- | --------------------------------------------------------------------- |
| `name()`        | `String`  | имя события                                                           |
| `payload()`     | `Object`  | данные события или `null`, см. [Список событий](/events/reference.md) |
| `cancellable()` | `boolean` | можно ли отменить                                                     |
| `cancelled()`   | `boolean` | уже отменено этим скриптом или другим                                 |
| `cancel()`      | `void`    | отменить: Quick не выполнит действие, к которому относится событие    |

Данные приводятся к нужному типу: `int slot = (Integer) event.payload()`, `PacketInfo packet = (PacketInfo) event.payload()`.

## Типизированные события

Классы лежат в `hex.script.api.event`. Все они наследуют `Event`, поэтому `cancellable()`, `cancelled()`, `cancel()` и `name()` есть у каждого. Объект тоже переиспользуется, так что нужные значения лучше забирать сразу.

| Класс         | Когда                                        | Свои поля                                                                                                      |
| ------------- | -------------------------------------------- | -------------------------------------------------------------------------------------------------------------- |
| `TickEvent`   | тик клиента, пока игрок в мире               | нет                                                                                                            |
| `KeyEvent`    | клавишу нажали или отпустили                 | `key()`, `scancode()`, `modifiers()`, `pressed()`, `released()`, `shift()`, `control()`, `alt()`, `screen()`   |
| `MouseEvent`  | кнопка мыши, в том числе при открытом экране | `button()`, `left()`, `right()`, `middle()`, `pressed()`, `released()`, `x()`, `y()`, `screen()`               |
| `ScrollEvent` | прокрутка колеса мыши                        | `amount()` (вверх положительное), `horizontal()`, `up()`, `screen()`                                           |
| `ScreenEvent` | экран открылся или закрылся                  | `opened()`, `closed()`, `screen()`; при закрытии это закрытый экран                                            |
| `ChatEvent`   | сообщение в чате                             | `message()`, `text()`, `source()`, `player()`, `server()`, `client()`, `contains()`, `startsWith()`, `after()` |
| `SoundEvent`  | начал играть звук                            | `id()`, `is()`, `source()`, `volume()`, `pitch()`, `x()`, `y()`, `z()`; отменить нельзя                        |

Если отменить `MouseEvent`, клик не дойдёт до игры. Отмена `ChatEvent` скрывает сообщение только на клиенте, сервер об этом не узнаёт. `ChatEvent.after("Баланс: ")` возвращает остаток строки после префикса, так проще доставать числа из сообщений.

### Экран в событии

У событий ввода `screen()` возвращает экран, открытый в момент события, с данными на этот момент. Такой же объект можно получить в любом месте через `client().screen()`.

| Метод                                            | Тип       | Описание                                                         |
| ------------------------------------------------ | --------- | ---------------------------------------------------------------- |
| `open()`                                         | `boolean` | открыт ли какой-нибудь экран                                     |
| `kind()`                                         | `int`     | `Screen.NONE`, `CHAT`, `INVENTORY`, `CONTAINER`, `MENU`, `OTHER` |
| `chat()`, `inventory()`, `container()`, `menu()` | `boolean` | быстрые проверки                                                 |
| `type()`                                         | `String`  | короткое имя класса экрана, например `"ChatScreen"`              |
| `title()`                                        | `String`  | заголовок без форматирования                                     |
| `is(name)`                                       | `boolean` | содержит ли имя класса эту строку, без учёта регистра            |

## Частые ошибки

* Подписка в конструкторе вместо `activate()`. При первом выключении она снимется и больше не восстановится.
* Сохранение `event` в поле. После выхода из обработчика объект пустой или уже занят следующим событием.
* Тяжёлая работа в `tick` или `packetReceive`. Это главный поток, и игра ждёт, пока обработчик завершится.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.quickclient.cc/events/basics.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
