API плагина
Для тех, кто пишет свой плагин и хочет дружить с LastMines, а не парсить его YAML руками.
Если коротко: API у LastMines маленький и без затей. Один интерфейс на десяток методов, набор обычных
Bukkit-событий — и всё. Никакого Kotlin, никаких CompletableFuture — вызовы дешёвые (там просто
чтение из памяти плагина), поэтому всё синхронно и сразу возвращает результат. Магии нет.
Как достучаться
Через ServicesManager API не регистрируется — вместо этого простой статический провайдер:
LastMinesAPI api = LastMinesProvider.getApi();
Выставляется один раз в onEnable() самого LastMines. Если дёрнуть getApi() раньше,
чем LastMines включился, — получите null. На практике это значит: ставьте
softdepend: [LastMines] себе в plugin.yml и не трогайте API до собственного
onEnable().
setApi() кидает исключение, если вызвать его дважды — так что даже не пытайтесь подменить
провайдер сами, это защищено от повторной инициализации.
Что умеет LastMinesAPI
Вот все методы интерфейса как есть, без причёсывания:
Mine getMine(String id);
Collection<Mine> getMines();
void openGui(Player player, String id);
boolean isWithinRadius(Mine mine, Location location, double radius);
Collection<Mine> getMinesInRadius(Location location, double radius);
void resetMine(String id);
Mine getMineAt(Location location);
Mine getMineAt(Player player);
getMine/getMines — это прямой доступ к внутренней карте шахт плагина, ничего не
копируется. Объект Mine, который вы получаете, — тот же самый, что живёт внутри LastMines, а не
его снимок. Долго держать ссылку на него в памяти не стоит — если шахту удалят, объект просто «протухнет».
Надёжнее хранить у себя ID шахты и каждый раз получать актуальный Mine заново.
getMineAt(Location) — линейный перебор всех загруженных шахт с проверкой попадания в
bounding box. Если у вас на сервере пара сотен шахт и вы дёргаете этот метод каждый тик на каждого игрока —
сами себе злобный буратино, лучше закешируйте результат хотя бы на несколько тиков.
isWithinRadius и getMinesInRadius считают расстояние от центра
шахты по прямой — обычная евклидова дистанция до середины между pos1 и pos2.
Это не тот же алгоритм, что используется внутри для [radius:N] в действиях — там
расстояние считается до ближайшей грани параллелепипеда (см. Геометрия и
позиции). Так исторически сложилось: публичный API писался отдельно и проще. Если нужна логика
«у стенки шахты» — считайте её сами по pos1/pos2.
События
Обычные Bukkit-события, все лежат в пакете ru.last.mines.api.events. Слушаются как угодно,
через @EventHandler — ничего специфичного для LastMines тут нет.
| Событие | Отменяемое | Когда стреляет |
|---|---|---|
MineCreateEvent | нет | шахта создана через /lastmines create |
MineDeleteEvent | да | прямо перед удалением — отмените, и шахта останется жить |
MineLoadEvent / MineUnloadEvent | нет | при загрузке/выгрузке (рестарт, /reload, ручной анлоад) |
MinePreResetEvent | да | прямо перед началом заполнения блоков |
MineResetEvent | нет | когда заполнение реально закончилось, не сразу — см. ниже |
MineUpdateRarityEvent | нет | при смене текущей/следующей редкости, до самого сброса блоков |
MineTeleportEvent | да | телепорт к шахте по команде/кнопке (не автосброс) |
MineBlockBreakEvent | да | игрок ломает блок в шахте, до всех внутренних проверок плагина |
MineResetEvent прилетает не там, где кажется
Сброс шахты — не мгновенная операция. Если шахта большая, заполнение размазывается по нескольким тикам:
плагин расставляет блоки в цикле, но следит за временем — как только на один тик уходит больше ~10мс или
уже поставлено больше 10000 блоков, он останавливается и продолжает на следующем. MinePreResetEvent
стреляет один раз и сразу, а вот MineResetEvent — только когда всё реально расставлено, то
есть может прилететь через несколько тиков после вызова сброса. Для «шахта обновилась, скажи игрокам» —
самое то. А если ждать его синхронно сразу после resetMine() в том же методе — не дождётесь.
MineBlockBreakEvent идёт раньше прав и зачарований
Порядок в обработчике поломки блока такой: сначала летит ваш MineBlockBreakEvent, и только
потом плагин сам проверяет право на шахту (см. права доступа) и требования к
зачарованиям кирки. Отмените событие на своей стороне — и плагин даже не дойдёт до своих проверок. Удобно,
если хотите добавить свою причину отказа поверх встроенных, не трогая конфиги LastMines.
Подключаем как зависимость
LastMines публикуется в собственный maven-репозиторий LastStudio, JitPack не нужен:
repositories {
maven("https://repo.laststudio.space/releases")
}
dependencies {
compileOnly("ru.last.mines:lastmines:0.2")
}
И в своём plugin.yml:
softdepend: [LastMines]
Пример: своя причина отказа на поломку блока
@EventHandler
public void onMineBreak(MineBlockBreakEvent event) {
Player player = event.getPlayer();
if (!player.hasPermission("myplugin.mine.access")) {
event.setCancelled(true);
player.sendMessage("У тебя нет доступа к этой шахте!");
}
}
Просто, без сюрпризов — как и весь остальной API, собственно.