- Поддерживаемые версии
- 1.12
Доброго времени суток. Я в прошлый раз обещал написать второй туториал насчет плагинов на следующий день, но к сожалению, этот день затянулся РОВНО НА ДВА МЕСЯЦА. Прошу прощения.
Итак, снова всем привет. В прошлый раз мы научились создавать плагин, но все-же он не имел функционала. В этот раз мы сделаем следующее:
1) Сделаем свое сообщение при входе
2) Попробуем выключить TAB (автодополнение)
3) Будем проигрывать звук ui.toast.challenge_complete (звук выполнения испытания) когда на сервер заходит администратор или игрок с OP
4) Добавим свою команду
5) Добавим аргументы для команды
Туториалы: 1) Написание плагинов 2) Написание плагинов - Эвенты и команды 3) Bukkit API - Сущности |
И снова хочу сказать "извините". Дело в том, что я поменял жесткий диск, и потерял старый проект.
Сейчас мне нужно написать один плагин для себя, и по мере написания плагина я буду писать туториалы. Трудностей возникнуть не должно - поменялись только названия классов и пакетов.
P.S. В конце я напишу весь код целиком, чтобы не возникло банальных вопросов.
1) Создаем свое сообщение при входе
Для начала, напишем в главный класс код для регистрации класса эвента:
в тело onEnable() запишем
getServer().getPluginManager().registerEvents(new EventsListener(), this);
Что значат эти слова? Я не буду разбирать все досконально, расскажу только об аргументах, чтобы не возникло путаницы.
new EventsListener()
- это "новый слушатель эвентов". В этом месте вместо EventsListener можно написать что угодно, но лучше было бы чтобы слово содержало смысл. this - главный класс, в котором импортируется JavaPlugin.IDE загорится ошибкой, и предложит создать класс EventsListener. Создаем его, и открываем.
Там где
public class EventsListener
дописываем implements Listener
. implements - это реализация интерфейса. Это может быть непонятным, поэтому советую почитать про интерфейсы, классы и абстрактные классы.В тело пишем аннотацию @EventHandler, она указывает что это эвент.
Сразу после аннотации пишем
public void название_эвента(Эвент e)
Где "название_эвента" можно написать что угодно, где "Эвент" - именно тот эвент, который нам нужен.
Итак, вернемся к идее. Что нам нужно? Свое сообщение при входе. Значит эвент будет PlayerJoinEvent.
Cписок эвентов можно посмотреть тут. Это не все эвенты, а только связанные с игроком.
Продолжим писать код.
У нас получилось
public void onPlayerJoin(PlayerJoinEvent e)
IDE предложит импорт этого эвента, импортируем.
Теперь в тело пишем e.setJoinMessage(e.getPlayer().getName()+"§a зашел на сервер!");
Разберем. e.setJoinMessage - дословно, это установка сообщения при входе. e.getPlayer().getName() - это получение имени игрока. При входе, у нас будет примерно такое:
Admin зашел на сервер!
Готово.
2) Звук при входе, если игрок администратор
Теперь, все в том же эвенте, пишем следующие строки:
Java:
if (e.getPlayer().isOp() || e.getPlayer().hasPermission("plugin.admin")) { // проверка игрока на OP или право // "plugin.admin", где plugin -
// название плагина
for (Player pp : Bukkit.getOnlinePlayers()) {
pp.playSound(pp.getLocation(), Sound.UI_TOAST_CHALLENGE_COMPLETE, 100.0F, 100.0F);
}
/*
* проигрывание звука
*
* .getLocation - локация игрока,
*
* Sound.UI_TOAST_CHALLENGE_COMPLETE - звук выполненного испытания,
*
* 100.0F и 100.0F я честно не помню что значат, вроде тональность и дальность
* звука.
*
* Попробуйте поменять эти два значения.
*/
e.setJoinMessage("§cАдминистратор §e" + e.getPlayer.getName() + "§c зашел на сервер!");
}
3) Отмена использования TAB'а
В том же самом классе (EventListener) напишите этот код:
Java:
@EventHandler
public void onPlayerUseTab(TabCompleteEvent e) {
if (!e.getSender().hasPermission("plugin.admin") || !e.getSender().isOp()) {
e.setCancelled(true);
}
}
4) Добавление команды
В большинстве туториалов предлагают создание команды в главном классе, но мы как тру-кодеры будем делать все отдельно.
Вернемся к onEnable() главного класса, допишем в конец тела следующую строку:
getServer().getPluginCommand("команда").setExecutor(new название_класса_команды());
где вместо "команда" может быть все что угодно, и... вместо "название_класса_команды" тоже все что угодно. Но придерживайтесь правила - это "все что угодно" должно иметь смысл. У меня будет называться команда "player" и класс "PlayerCMD".
Итак, IDE скажет что у нас нет такого класса, создаем его.
После public class PlayerCMD добавим implements CommandExecutor.
IDE предлагает добавить недобавленные методы, добавляем.
Класс принял такой вид:
Java:
public class PlayerCMD implements CommandExecutor {
@Override //переопределяем метод
public boolean onCommand(CommandSender sender, Command cmd, String str, String[] args) {
//CommandSender - отправляющий команду, Command - команда, String str я никогда не использовал, мне хватало cmd, String[] args - массив аргументов.
return false; //вернем "ложь" если команда выполнена неправильно (настраивается в plugin.yml)
}
}
Но она ничего не делает, а это не интересно, поэтому перейдем к аргументам...
5) Аргументы
Java:
@Override
public boolean onCommand(CommandSender sender, Command cmd, String str, String[] args) {
Player target = sender.getServer().getPlayer(args[0]); //аргумент 1 (отсчет идет с нуля, поэтому в массивах число=число+1)
if (sender.hasPermission("grief.playerinfo") && (args.length < 1 || args.length > 1)) { //если игрок имеет правo "плагин.playerinfo"
sender.sendMessage("§eИмя игрока: §c"+target.getName());
sender.sendMessage("§eКоординаты: §c"+target.getLocation());
sender.sendMessage("§eРежим: §c"+target.getGameMode());
sender.sendMessage("§eИмеет ОП: §c"+target.isOp());
if (sender.hasPermission("grief.playerinfo.adv")) { //если игрок имеет право "плагин.playerinfo.adv" (adv - advanced, улучшенный)
sender.sendMessage("§eIP: §c"+target.getAddress());
sender.sendMessage("§eUUID: §c"+target.getUniqueId());
}
return true; //вернем правду, команда выполнена верно
}
return false;
}
Как сделать объявления (аналог /bc в Essentials):
Java:
@Override
public boolean onCommand(CommandSender sender, Command cmd, String str, String[] args) {
if (sender.hasPermission("grief.broadcast")) {
if (args.length!=0) {
String message = ""; //инициализация переменной
for (int i = 0; i < args.length; i++) { //цикл, который проходит по массиву аргументов
message = String.valueOf(message)+args[i]+""; //сбор всех аргументов в одно целое
}
message = ChatColor.translateAlternateColorCodes('&', message); //перевод & (цветовые коды)
Bukkit.broadcastMessage("§7[§a"+sender.getName()+"§7] "+message); // показываем всем свое сообщение
} else {
sender.sendMessage("§fИспользуйте /broadcast <сообщение>"); //можно настроить в plugin.yml сообщение, а можно и так)
}
}
sender.sendMessage("§cУ Вас нет прав!"); //нет прав!
return true;
}
Мы вводим: /broadcast 1 2 3 4 4 5 6 7
Все видят:
В прошлом уроке мы использовали plugin.yml. Он был довольно маленького содержания, но сейчас оно пополниться.
Нам нужно заполнить plugin.yml командами и правами, тут нет ничего сложного, и можно понять по шаблону
Целиком файл выглядит так:
YAML:
name: Grief
main: me.mycompanyname.grief.Grief
version: 1.0
commands: #команды
player: #команда
description: Описание, отображается в /help
permission: grief.playerinfo #право
usage: /<command> [player]
broadcast:
description: Возможность писать объявления
permission: grief.broadcast
usage: /<command> [сообщение]
permissions: #права
grief.playerinfo.adv: #право
description: Описание
children: #"дети" права. кажется, это нужно чтобы не вводить в файл с правами -grief.playerinfo.adv
#и -grief.playerinfo, и использовать -grief.playerinfo.* . Если у Вас одно "детское" право как у #меня, то можно не использовать
grief.playerinfo: true #является
grief.playerinfo:
description: Дает право на просмотр базовой информации об игроке
grief.admin:
description: Обход некоторых запретов и уникальное сообщение при входе
Задаем вопросы, указываем на ошибки, ожидаем третью часть - она будет совсем скоро, ну а теперь - до встречи!