> ## Documentation Index
> Fetch the complete documentation index at: https://docs.cakestudio.fun/llms.txt
> Use this file to discover all available pages before exploring further.

# CakeRegions API

> Полное руководство для разработчиков по созданию аддонов и интеграций с CakeRegionsPlus.

CakeRegionsPlus предоставляет мощный и изолированный программный интерфейс для взаимодействия с системой приватных регионов. API уже встроено в основной плагин — вам **не нужно** устанавливать его как отдельный `.jar`.
Более подробную инструкцию по использованию API вы можете найти [**здесь**](https://github.com/CakesStudio/CakeRegionsAPI/blob/main/DOCUMENTATION.md).

<CardGroup cols={2}>
  <Card title="GitHub Репозиторий" icon="github" href="https://github.com/CakesStudio/CakeRegionsAPI">
    Исходный код и последние релизы API.
  </Card>

  <Card title="JitPack" icon="box" href="https://jitpack.io/#CakesStudio/CakeRegionsAPI">
    Подключение зависимости в ваш проект.
  </Card>
</CardGroup>

## 🚀 Подключение

Используйте `compileOnly` (Gradle) или `provided` (Maven), чтобы API не попадало в ваш итоговый JAR-файл.

### Gradle (Groovy)

```gradle theme={null}
repositories {
    maven { url 'https://jitpack.io' }
}

dependencies {
    compileOnly 'com.github.CakesStudio:CakeRegionsAPI:VERSION'
}
```

### Maven

```xml theme={null}
<repositories>
    <repository>
        <id>jitpack.io</id>
        <url>https://jitpack.io</url>
    </repository>
</repositories>

<dependencies>
    <dependency>
        <groupId>com.github.CakesStudio</groupId>
        <artifactId>CakeRegionsAPI</artifactId>
        <version>VERSION</version>
        <scope>provided</scope>
    </dependency>
</dependencies>
```

*(Замените `VERSION` на актуальную версию, например `2.0.0`)*

<Warning>
  **Важно:** Основное ядро CakeRegionsPlus выполняет релокацию библиотек `net.kyori` (Adventure) и `com.tcoded` (FoliaLib).
  Чтобы избежать ошибки **NoSuchMethodError**, ваш аддон **ОБЯЗАН** выполнить релокацию этих библиотек в тот же пакет:

  ```gradle theme={null}
  tasks.shadowJar {
      relocate 'net.kyori', 'dev.cakestudio.cakeregions.libs.kyori'
      relocate 'com.tcoded.folialib', 'dev.cakestudio.cakeregions.libs.folialib'
  }
  ```
</Warning>

***

## 🧩 Система Аддонов

CakeRegionsPlus включает полноценную управляемую систему аддонов с изолированным жизненным циклом. Аддоны — это JAR-файлы, которые помещаются в папку `plugins/CakeRegionsPlus/addons/`.

### 1. Метаданные (addon.yml)

Создайте файл `addon.yml` в папке `resources` вашего проекта:

```yaml theme={null}
name: MyAwesomeAddon
main: com.example.myaddon.MyAddon
version: 1.0.0
api-version: '2.0.0'       # Минимальная поддерживаемая версия CakeRegions API
folia-supported: true       # Поддержка серверов Folia
description: "Пример описания аддона"
authors: [ "Developer" ]
depend: []                  # Обязательные зависимости
soft-depend: []             # Необязательные зависимости
```

### 2. Реализация (AbstractAddon)

Наследуйте ваш главный класс от `AbstractAddon`. Это обеспечит **автоматическую очистку** ресурсов (слушателей, команд, задач, открытых меню) при выключении.

```java theme={null}
import dev.cakestudio.cakeregionsapi.addon.AbstractAddon;

public class MyAddon extends AbstractAddon {

    @Override
    protected void onEnable() {
        saveDefaultConfig(); // Конфиг сохранится в /plugins/CakeRegionsPlus/addons/MyAddon/
        registerListener(new MyListener());
        registerCommand(new MyCommand());
    }

    @Override
    protected void onDisable() {
        // Логика при выключении (сохранение данных и т.д.)
    }
}
```

<Note>
  **Автоматическая очистка ресурсов:** При отключении аддона CakeRegions автоматически:

  * Выгружает все зарегистрированные через `registerListener()` слушатели событий.
  * Удаляет все зарегистрированные через `registerCommand()` команды.
  * Отменяет все задачи, запланированные методами `runTask*()`.
  * Закрывает все GUI-меню, открытые вашим аддоном.
</Note>

### 3. Конфигурация аддона

`AbstractAddon` предоставляет встроенное управление конфигурацией, аналогичное `JavaPlugin`:

```java theme={null}
// Сохранить дефолтный config.yml из ресурсов JAR
saveDefaultConfig();

// Прочитать значение
String value = getConfig().getString("my-key", "default");

// Перезагрузить конфиг с диска
reloadConfig();

// Сохранить текущее состояние конфига
saveConfig();

// Сохранить произвольный ресурс из JAR
saveResource("data/items.yml", false);
```

Все файлы конфигурации аддона хранятся в `plugins/CakeRegionsPlus/addons/<имя_аддона>/`.

***

## ⚡ Потоки и Folia (Concurrency)

Для корректной работы на **Folia**, Paper и Spigot используйте встроенные методы планировщика. Это гарантирует безопасность региональных потоков и автоматическую отмену задач при выгрузке аддона.

```java theme={null}
// Асинхронная задача
runTaskAsync(() -> {
    // Тяжелая логика в фоне
});

// Задача с задержкой (20 тиков = 1 секунда)
runTaskLaterAsync(() -> {
    // Выполнить через 1 секунду
}, 20L);

// Повторяющаяся задача (каждые 5 минут)
runTaskTimerAsync(() -> {
    // Периодическая логика
}, 0L, 20L * 60 * 5);
```

***

## 🛠️ Основные методы API

Доступ к API осуществляется через `CakeRegionsAPI.getApi()`.

```java theme={null}
import dev.cakestudio.cakeregionsapi.CakeRegionsAPI;
import dev.cakestudio.cakeregionsapi.api.IRegionsAPI;

IRegionsAPI api = CakeRegionsAPI.getApi();
```

### 🗺️ Регионы (IRegion)

Поиск, создание и управление регионами:

```java theme={null}
// Получить регион в определённой точке
Optional<IRegion> region = api.getRegionAt(location);

// Получить регион по ID
Optional<IRegion> region = api.getRegionById("abc-123");

// Проверить, защищена ли локация
boolean isProtected = api.isProtected(location);

// Проверить, может ли игрок строить в локации
boolean canBuild = api.canBuild(player, location);

// Получить все регионы игрока (создатель/владелец/участник)
List<IRegion> regions = api.getRegionsForPlayer(player);

// Получить регионы, где игрок — создатель
List<IRegion> created = api.getRegionsByCreator(player);

// Получить все регионы на сервере
Collection<IRegion> all = api.getAllRegions();

// Создать регион
Optional<IRegion> newRegion = api.createRegion(player, location, protectionBlock);

// Удалить регион
api.deleteRegion(region);

// Асинхронно удалить регион и сломать блок
api.deleteRegionAndBlockAsync("region-id", true);

// Телепортировать игрока к региону
api.teleportToRegion(player, region);
```

### 📋 Объект IRegion

Когда вы получаете регион (`IRegion`), вам доступны следующие методы:

| Метод                        | Описание                                                               |
| :--------------------------- | :--------------------------------------------------------------------- |
| `getId()`                    | Уникальный ID региона                                                  |
| `getCenter()`                | `Location` центрального блока                                          |
| `getCreator()`               | `UUID` создателя                                                       |
| `getOwners()`                | `Set<UUID>` совладельцев                                               |
| `getMembers()`               | `Set<UUID>` участников                                                 |
| `getFullMembers()`           | Все участники (создатель + владельцы + участники)                      |
| `isActive()`                 | Активен ли регион (есть топливо/прочность)                             |
| `getDurability()`            | Текущая прочность                                                      |
| `getFuelExpiryDate()`        | Время истечения топлива (unix ms)                                      |
| `getRemainingFuel()`         | Остаток времени топлива в секундах                                     |
| `getAge()`                   | Возраст региона в секундах                                             |
| `isAutoAdd()`                | Включено ли автодобавление соклановцев                                 |
| `setAutoAdd(boolean)`        | Установить статус автодобавления соклановцев                           |
| `isFuelBar()`                | Отображается ли боссбар топлива владельцу                              |
| `setFuelBar(boolean)`        | Установить видимость боссбара топлива                                  |
| `getRole(UUID)`              | Получить строковый ID роли участника (например, `"owner"`, `"member"`) |
| `getFormattedCreationDate()` | Дата создания в читаемом формате                                       |
| `getProtectionBlockType()`   | Настройки типа блока привата (`IProtectionBlock`)                      |
| `getCuboid()`                | Куб, описывающий границы региона (`ICuboid`)                           |

#### Управление прочностью и топливом

```java theme={null}
region.repair(50);         // Починить на 50 ед.
region.damage(10);         // Нанести урон 10 ед.
region.setDurability(100); // Установить прочность

region.addFuel(3600);      // Добавить топливо (в секундах)
region.setFuel(7200);      // Установить время топлива
region.removeFuel(600);    // Убрать топливо
```

#### Проверка ролей

```java theme={null}
region.isCreator(uuid);    // Создатель ли
region.isOwner(uuid);      // Совладелец ли
region.isMember(uuid);     // Участник ли
region.isFullMember(uuid); // Любая роль
region.canBuild(uuid);     // Может ли строить
String role = region.getRole(uuid); // Получить роль (например, "owner", "member")
```

#### Метаданные и Теги (Tags)

Вы можете сохранять любые строковые метаданные прямо внутри региона. Они будут сохранены в базу данных:

```java theme={null}
region.setTag("custom_key", "custom_value"); // Установить значение
String value = region.getTag("custom_key");  // Получить значение
boolean hasTag = region.hasTag("custom_key");// Проверить существование
region.removeTag("custom_key");              // Удалить тег
Map<String, String> tags = region.getTags(); // Все теги (только для чтения)
```

***

### 👥 Управление участниками

```java theme={null}
// Добавить участника
api.addMember(region, target, false); // false = проверять лимиты

// Удалить участника
api.removeMember(region, target);

// Повысить до совладельца
api.addOwner(region, target, false);

// Понизить из совладельцев
api.removeOwner(region, target);

// Получить списки
List<OfflinePlayer> members = api.getRegionMembers(region);
List<OfflinePlayer> owners = api.getRegionOwners(region);
UUID creator = api.getRegionCreator(region);
```

***

### 🔐 Права участников (IPlayerPermissions)

```java theme={null}
IPlayerPermissions perms = api.getPlayerPermissions(region, player);

// Проверить право
boolean canAddMember = perms.hasPermission(RegionPermValue.ADD_MEMBER);

// Изменить права
perms.addPermission(RegionPermValue.ADD_FUEL);
perms.removePermission(RegionPermValue.MODIFY_PERMISSIONS);
perms.togglePermission(RegionPermValue.REMOVE_MEMBER);

// Сохранить изменения
region.setPermissions(player.getUniqueId(), perms);
```

**Доступные значения `RegionPermValue`:**

| Значение             | Описание                |
| :------------------- | :---------------------- |
| `ADD_FUEL`           | Добавление топлива      |
| `ADD_MEMBER`         | Добавление участников   |
| `REMOVE_MEMBER`      | Удаление участников     |
| `ADD_OWNER`          | Добавление совладельцев |
| `REMOVE_OWNER`       | Удаление совладельцев   |
| `MODIFY_PERMISSIONS` | Изменение прав          |

***

### 🏗️ Блоки привата (IProtectionBlock)

```java theme={null}
// Получить тип блока по ID
Optional<IProtectionBlock> block = api.getProtectionBlock("diamond");

// Получить все зарегистрированные типы
Collection<IProtectionBlock> types = api.getProtectionBlockTypes();
```

`IProtectionBlock` предоставляет полный доступ к настройкам из конфига:

| Метод                   | Описание                          |
| :---------------------- | :-------------------------------- |
| `getTypeId()`           | ID типа (напр. `"diamond"`)       |
| `getMaterial()`         | Материал блока                    |
| `getRadius()`           | Радиус защиты                     |
| `getMaxMembers()`       | Максимум участников               |
| `getEconomyProvider()`  | Провайдер экономики               |
| `getHologramEngine()`   | Движок голограмм                  |
| `getPlaceCost()`        | Стоимость установки               |
| `isFuelSystemEnabled()` | Включена ли система топлива       |
| `getHologram()`         | Настройки голограммы              |
| `getDurability()`       | Настройки прочности               |
| `getPlacementRules()`   | Правила размещения (биомы, блоки) |
| `getCraftData()`        | Настройки крафта                  |
| `getActions()`          | Действия при событиях             |
| `getRequirements()`     | Требования для установки          |

***

### 🔭 Голограммы

```java theme={null}
// Проверить, включены ли голограммы
boolean enabled = api.isHologramEnabled();

// Создать/удалить/обновить голограмму для региона
api.createHologram(region);
api.deleteHologram(region);
api.updateHologram(region);

// Массовые операции
api.recreateAllHolograms();
api.updateAllHolograms();

// Проверить наличие
boolean has = api.hasHologram(region);
```

***

### 💰 Экономика (IEconomyManager)

CakeRegionsPlus поддерживает несколько экономических провайдеров: **Vault**, **VaultUnlocked**, **BVault**, **PlayerPoints**, **XP** (стандартный опыт Minecraft). Каждый тип блока привата может использовать свой провайдер.

```java theme={null}
IEconomyManager economy = api.getEconomyManager();

// Получить баланс (дефолтная экономика)
double balance = economy.getBalance(player);

// Получить баланс в конкретной экономике
double xpBalance = economy.getBalance(player, "XP");

// Списать средства
if (economy.has(player, 500.0)) {
    economy.withdraw(player, 500.0);
}

// Пополнить
economy.deposit(player, 100.0);

// Форматировать
String formatted = economy.format(1500.0); // "1,500$"
```

#### Регистрация кастомной экономики

Если ваш аддон вводит собственную валюту, реализуйте интерфейс `IEconomyProvider`:

```java theme={null}
import dev.cakestudio.cakeregionsapi.api.manager.economy.IEconomyProvider;

public class GemsEconomy implements IEconomyProvider {

    @Override
    public String getName() { return "Gems"; }

    @Override
    public double getBalance(OfflinePlayer player) { /* ... */ }

    @Override
    public boolean has(OfflinePlayer player, double amount) { /* ... */ }

    @Override
    public boolean withdraw(OfflinePlayer player, double amount) { /* ... */ }

    @Override
    public boolean deposit(OfflinePlayer player, double amount) { /* ... */ }

    @Override
    public String format(double amount) { return amount + " 💎"; }
}

// Регистрация
api.getEconomyManager().registerProvider(new GemsEconomy());
```

После регистрации провайдер `Gems` можно указать в конфиге блока привата (`economy-provider: Gems`).

***

### 🔌 Кастомные предметы (IItemHookManager)

CakeRegionsPlus умеет распознавать и выдавать кастомные предметы из **ItemsAdder**, **Oraxen** и **Nexo**. Вы также можете добавить поддержку своего плагина предметов.

```java theme={null}
IItemHookManager itemHook = api.getItemHookManager();

// Получить ItemStack по строковому ID
ItemStack customItem = itemHook.getItem("oraxen:my_sword");

// Получить ID кастомного предмета из ItemStack
String itemId = itemHook.getItemId(customItem); // "oraxen:my_sword"
```

#### Регистрация своего провайдера кастомных предметов

```java theme={null}
import dev.cakestudio.cakeregionsapi.api.manager.item.IItemHookProvider;

IItemHookProvider provider = new IItemHookProvider() {
    @Override
    public @Nullable ItemStack getItem(@NonNull String id) {
        if (id.equalsIgnoreCase("heavy_core")) {
            ItemStack core = new ItemStack(Material.NETHERITE_BLOCK);
            ItemMeta meta = core.getItemMeta();
            meta.setDisplayName("Heavy Protection Core");
            core.setItemMeta(meta);
            return core;
        }
        return null;
    }

    @Override
    public @Nullable String getItemId(@NonNull ItemStack item) {
        // Идентифицировать предмет
        return null;
    }

    @Override
    public @NonNull String getPrefix() {
        return "mycustomitems"; // Обрабатывает "mycustomitems:heavy_core"
    }
};

// Регистрация и удаление
itemHook.registerProvider(provider);
itemHook.unregisterProvider(provider);
```

***

## 🗃️ Дополнительные Менеджеры API

Помимо основных методов, `IRegionsAPI` предоставляет доступ к специализированным менеджерам для гибкого управления всеми системами плагина:

### 🔋 Менеджер Топлива (IFuelManager)

Управление типами топлива и проверкой предметов:

```java theme={null}
IFuelManager fuelManager = api.getFuelManager();

// Найти тип топлива по предмету
Optional<IFuelType> fuelType = fuelManager.getFuelType(itemStack);
```

### 🔧 Менеджер Починки (IRepairManager)

Управление ремонтными материалами:

```java theme={null}
IRepairManager repairManager = api.getRepairManager();

// Найти ремонтный предмет
Optional<IRepairItem> repairItem = repairManager.getRepairItem(itemStack);
```

### 🎬 Менеджер Действий (IActionManager)

Выполнение кастомных цепочек действий (Actions):

```java theme={null}
IActionManager actionManager = api.getActionManager();

// Выполнить действие для игрока
actionManager.executeActions(player, actionsList);
```

### 📢 Менеджер Уведомлений (INotificationManager)

Отправка рейдов и предупреждений:

```java theme={null}
INotificationManager notificationManager = api.getNotificationManager();

// Отправить уведомление о рейде
notificationManager.sendRaidNotification(region, attackerEntity);
```

### 🌌 Менеджер Эффектов (IEffectsManager)

Визуальные эффекты вокруг блоков привата:

```java theme={null}
IEffectsManager effectsManager = api.getEffectsManager();

// Показать эффект границы региона игроку
effectsManager.showBorder(player, region);
```

### 🗂️ Менеджер Меню (IMenuManager)

Открытие кастомных инвентарей плагина:

```java theme={null}
IMenuManager menuManager = api.getMenuManager();

// Открыть меню информации о регионе
menuManager.openRegionInfoMenu(player, region);
```

### 📊 Менеджер Статистики (IStatsManager)

Получение статистики о регионах и рейдах игроков:

```java theme={null}
IStatsManager statsManager = api.getStatsManager();

// Получить количество рейдов игрока
int raidCount = statsManager.getPlayerRaidCount(playerId);

// Получить топ регионов по прочности
List<IRegion> topRegions = statsManager.getTopRegionsByDurability(10);
```

### 👁️ Визуализатор Регионов (IRegionVisualizer)

Управление визуальным показом границ приватов:

```java theme={null}
IRegionVisualizer visualizer = api.getRegionVisualizer();

// Показать границы региона игроку
visualizer.showBoundary(player, region);

// Скрыть границы
visualizer.hideBoundary(player);
```

### ⚙️ Настройки Игрока (Player Settings)

Управление персональными настройками игроков (например, отображением BossBar):

```java theme={null}
// Проверить, включен ли боссбар топлива у игрока
boolean enabled = api.isPlayerFuelBarEnabled(player);

// Переключить боссбар топлива для игрока
api.setPlayerFuelBar(player, false);
```

### ⚡ Улучшения и Бустеры (Upgrades & Boosters)

Система улучшений и PVE бустеров предоставляет полные методы для расширения функционала приватов:

```java theme={null}
// Получить уровень улучшения радиуса
int level = region.getRadiusUpgradeLevel();

// Установить уровень улучшения радиуса
region.setRadiusUpgradeLevel(3);

// Проверить, активен и включен ли бустер в регионе
boolean hasBooster = region.hasActiveBooster("crop_growth");

// Активировать временный бустер на 1 час (3600 секунд)
region.activateBooster("spawner_speed", 3600);

// Активировать перманентный бустер навсегда
region.activatePermanentBooster("no_fuel_decay");

// Проверить, включен ли бустер игроком
boolean enabled = region.isBoosterEnabled("crop_growth");

// Включить/выключить бустер игроком
region.setBoosterEnabled("crop_growth", false);
```

***

## 📅 Система Событий (Events)

Все события находятся в пакете `dev.cakestudio.cakeregionsapi.api.event` и наследуют стандартный класс `org.bukkit.event.Event`. Большинство событий поддерживают `Cancellable`.

| Событие                       | Описание                                 | Отменяемое | Ключевые данные                                                                         |
| :---------------------------- | :--------------------------------------- | :--------: | :-------------------------------------------------------------------------------------- |
| `RegionCreateEvent`           | Создание нового региона                  |      ✅     | `getPlayer()`, `getRegion()`, `getIProtectionBlockType()`                               |
| `RegionDestroyEvent`          | Удаление региона                         |      ✅     | `getRegion()`, `getDestroyer()`, `getCause()`, `setDropItem()`                          |
| `RegionExplosionEvent`        | Взрыв затрагивает регион                 |      ✅     | `getRegion()`, `getExplosionSource()`, `getAffectedBlocks()`                            |
| `RegionDurabilityChangeEvent` | Изменение прочности                      |      ✅     | `getRegion()`, `getOldDurability()`, `getNewDurability()`                               |
| `RegionMemberAddEvent`        | Добавление участника                     |      ✅     | `getRegion()`, `getMember()`                                                            |
| `RegionMemberRemoveEvent`     | Удаление участника                       |      ✅     | `getRegion()`, `getMember()`                                                            |
| `RegionOwnerAddEvent`         | Добавление совладельца                   |      ✅     | `getRegion()`, `getMember()`                                                            |
| `RegionOwnerRemoveEvent`      | Удаление совладельца                     |      ✅     | `getRegion()`, `getMember()`                                                            |
| `RegionEnterEvent`            | Вход игрока в зону региона               |      ❌     | `getPlayer()`, `getRegion()`                                                            |
| `RegionLeaveEvent`            | Выход игрока из зоны региона             |      ❌     | `getPlayer()`, `getRegion()`                                                            |
| `RegionFuelAddEvent`          | Пополнение топлива региона               |      ✅     | `getPlayer()`, `getRegion()`, `getFuelItem()`, `getFuelPoints()`                        |
| `RegionFuelExpireEvent`       | Истечение срока действия топлива региона |      ❌     | `getRegion()`                                                                           |
| `RegionRepairEvent`           | Починка региона ремонтным предметом      |      ✅     | `getPlayer()`, `getRegion()`, `getRepairItem()`, `getRepairPoints()`                    |
| `RegionTeleportEvent`         | Телепортация игрока к региону            |      ✅     | `getPlayer()`, `getRegion()`                                                            |
| `RegionRaidStartEvent`        | Обнаружение начала рейда на регион       |      ❌     | `getRegion()`, `getRaider()`, `getDamageSource()`                                       |
| `RegionPermissionChangeEvent` | Изменение прав участника в регионе       |      ✅     | `getRegion()`, `getTarget()`, `getPermission()`, `isNewState()`                         |
| `RegionOwnerTransferEvent`    | Передача владения регионом (creator)     |      ✅     | `getRegion()`, `getPreviousCreator()`, `getNewCreator()`                                |
| `RegionUpgradeEvent`          | Покупка улучшения уровня региона         |      ✅     | `getRegion()`, `getPlayer()`, `getUpgradeType()`, `getPreviousLevel()`, `getNewLevel()` |
| `RegionBoosterActivateEvent`  | Активация PVE бустера в регионе          |      ✅     | `getRegion()`, `getPlayer()`, `getBoosterId()`, `getDurationSeconds()`                  |
| `RegionBoosterExpireEvent`    | Истечение срока действия бустера         |      ❌     | `getRegion()`, `getBoosterId()`                                                         |
| `RegionBoosterToggleEvent`    | Переключение игроком активности бустера  |      ✅     | `getRegion()`, `getPlayer()`, `getBoosterId()`, `isNewEnabledState()`                   |

`RegionDestroyEvent` содержит перечисление **DestroyCause** со значениями:

* `PLAYER_BREAK` — регион сломан игроком.
* `EXPLOSION` — регион уничтожен взрывом.

### Пример слушателя

```java theme={null}
import dev.cakestudio.cakeregionsapi.api.event.RegionCreateEvent;
import dev.cakestudio.cakeregionsapi.api.event.RegionDestroyEvent;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;

public class MyListener implements Listener {

    @EventHandler
    public void onRegionCreate(RegionCreateEvent event) {
        String regionId = event.getRegion().getId();
        event.getPlayer().sendMessage("Регион " + regionId + " создан!");
    }

    @EventHandler
    public void onRegionDestroy(RegionDestroyEvent event) {
        if (event.getCause() == RegionDestroyEvent.DestroyCause.EXPLOSION) {
            event.setDropItem(false); // Не дропать предмет при взрыве
        }
    }
}
```

***

## 🎯 Полный пример аддона

Полный рабочий пример аддона доступен в репозитории: [**example\_addon**](https://github.com/CakesStudio/CakeRegionsAPI/tree/main/example_addon)

### Структура проекта

```
MyAddon/
├── build.gradle
├── src/main/
│   ├── java/com/example/myaddon/
│   │   ├── MyAddon.java
│   │   └── MyListener.java
│   └── resources/
│       ├── addon.yml
│       └── config.yml
```

### build.gradle

```gradle theme={null}
plugins {
    id 'java'
    id "io.github.goooler.shadow" version "8.1.8"
}

repositories {
    mavenCentral()
    maven { url = 'https://repo.papermc.io/repository/maven-public/' }
    maven { url = 'https://jitpack.io/' }
    maven { url = 'https://repo.tcoded.com/releases' }
}

dependencies {
    compileOnly 'com.github.CakesStudio:CakeRegionsAPI:2.0.0'
    compileOnly 'com.destroystokyo.paper:paper-api:1.16.5-R0.1-SNAPSHOT'
    compileOnly "com.tcoded:FoliaLib:0.5.1"
    compileOnly 'net.kyori:adventure-platform-bukkit:4.4.1'
    compileOnly 'net.kyori:adventure-text-minimessage:4.26.1'
}

java {
    toolchain.languageVersion = JavaLanguageVersion.of(17)
}

tasks.shadowJar {
    archiveFileName.set("MyAddon-${version}.jar")

    // Обязательная релокация!
    relocate 'net.kyori', 'dev.cakestudio.cakeregions.libs.kyori'
    relocate 'com.tcoded.folialib', 'dev.cakestudio.cakeregions.libs.folialib'
}

build.dependsOn shadowJar
```

### MyAddon.java

```java theme={null}
import dev.cakestudio.cakeregionsapi.addon.AbstractAddon;

public class MyAddon extends AbstractAddon {

    @Override
    protected void onEnable() {
        saveDefaultConfig();
        getLogger().info("MyAddon v" + getDescription().version() + " enabled!");
        registerListener(new MyListener(this));
    }

    @Override
    protected void onDisable() {
        getLogger().info("MyAddon disabled.");
    }
}
```

### addon.yml

```yaml theme={null}
name: MyAddon
main: com.example.myaddon.MyAddon
version: 1.0.0
api-version: '2.0.0'
folia-supported: true
description: "Мой первый аддон для CakeRegions"
authors: [ "Developer" ]
```

***

## 🧰 Утилиты API

| Метод                                   | Описание                                    |
| :-------------------------------------- | :------------------------------------------ |
| `api.getPlugin()`                       | Экземпляр `JavaPlugin` основного плагина    |
| `api.getFoliaLib()`                     | Экземпляр `FoliaLib` для планирования задач |
| `api.getDataFolder()`                   | Папка данных плагина                        |
| `api.registerCommand(cmd)`              | Динамическая регистрация команды            |
| `api.unregisterCommand(cmd)`            | Удаление команды                            |
| `api.toggleRegionCreation(player)`      | Переключить создание регионов для игрока    |
| `api.isCreationDisabled(player)`        | Проверить, отключено ли создание            |
| `api.setCreationDisabled(player, bool)` | Установить запрет создания                  |
| `api.getPlayerRegionLimit(player)`      | Лимит регионов для игрока                   |
| `api.isAreaOverlapping(cuboid)`         | Проверить пересечение областей              |
