Войти или зарегистрироваться
  • Вы находитесь в сообществе Rubukkit. Мы - администраторы серверов Minecraft, разрабатываем собственные плагины и переводим на различные языки плагины наших коллег из других стран.

Стартап Очень простые плагины,или же учим ивенты!

Метки:
Теги Теги
плагины

Nikolai_Faint

Активный участник
Пользователь
Баллы
96
Имя в Minecraft
fcode0xb
Привет. Сегодня я попытаюсь объяснить пару простых ивентов,для новичков и попробую "научить" вас кодить легкие плагины с конфигом.
И так,начнем с ивентов которые на моё мнение нужны для сервера,это ивенты:
OnJoinEvent
PlayerDeathEvent
BlockBreakEvent
PlayerInteractEvent

Думаю тут все понятно)
И так начнем с первого,напишем для него достаточно простой код,с конфигом.
Внимание! Все плагины будем делать в одном классе! :confused:
Для начала простой код:
Код:
package me.faint.joiner;

import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.plugin.java.JavaPlugin;

public class Main
    extends JavaPlugin
    implements Listener{
Импортировали пакеты,сделали класс. (Больше и не надо).
Теперь запуск плагина! Добавляем к коду еще один кусок кода.
Код:
package me.faint.joiner;

import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.plugin.java.JavaPlugin;

public class Main
    extends JavaPlugin
    implements Listener{
@Override
    public void onEnable(){
    Bukkit.getConsoleSender().sendMessage("§6[Joiner] Plugin loaded!");
    Bukkit.getServer().getPluginManager().registerEvents(this, this);
    saveDefaultConfig();
    reloadConfig();
    }
Добавили метод onEnable,сделали сообщение в консоль при включении,сохранили и перезагрузили конфиг,и зарегистрировали ивенты.
Внимание! Я не юзаю метод onDisable!
Теперь нам надо добавить сам ивент,и действие к нему.
Код:
package me.faint.joiner;

import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.plugin.java.JavaPlugin;

public class Main
    extends JavaPlugin
    implements Listener{
    @Override
    public void onEnable(){
    Bukkit.getConsoleSender().sendMessage("§6[Joiner] Plugin loaded!");
    Bukkit.getServer().getPluginManager().registerEvents(this, this);
    saveDefaultConfig();
    reloadConfig();
    }
    @EventHandler
     public void Join(PlayerJoinEvent e) {
        String s = getConfig().getString("join");
        s = s.replace("&", "\u00a7");
        Player p = e.getPlayer();
        p.sendMessage(s);
    }
}
Тут все тоже довольно просто,получаем строку и отсылаем сообщение.
Можно разными способами отсылать ивент:
- Чат
- Таб
- Скор борд
- Босс бар
- Актион бар
Но я предпочитаю юзать титлы

И в самом низу будет вариация с титлом.
Теперь самое главное! plugin.yml & config.yml
GqjIx27U2FY.jpg
cyi6QxTdHUU.jpg


Тоже самое делаем с config.yml!

Теперь заполняем!
PLUGIN.YML
name: Joiner - Имя плагина
description: Base plugin by pack Faint. - Описание
author: Faint - Автор
version: 1.0 - Версия
main: me.faint.joiner.Main - Путь к основному классу (Там где onEnable)
commands: - Команды
CONFIG.YML
join: '&4Добро пожаловать на сервер' - Так как мы указали одну строку (join) то наше сообщение будет браться именно из этой строки.
Теперь компилируем и радуемся!
P.S можно было указать игрока:

Код:
package me.faint.joiner;

import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.plugin.java.JavaPlugin;

public class Main
    extends JavaPlugin
    implements Listener{
    @Override
    public void onEnable(){
    Bukkit.getConsoleSender().sendMessage("§6[Joiner] Plugin loaded!");
    Bukkit.getServer().getPluginManager().registerEvents(this, this);
    saveDefaultConfig();
    reloadConfig();
    }
    @EventHandler
     public void onJoin(PlayerJoinEvent event){
     Player p = event.getPlayer();
    String s = getConfig().getString("join");
    s = s.replace("&", "\u00a7");
    s = s.replace("%player%", p.getDisplayName());
    p.sendMessage(s);
    }
}
CONFIG.YML
join: '&2[Вход] &4Добро пожаловать &2%player%'
Вывод в чат:
WgFuVA2M2E0.jpg


И так,как делать главный класс,получать строку,вы научились!
Теперь я просто буду объяснять код последующих ивентов)


Ивент: PlayerDeathEvent
Быстрая смерть

Быстрая смерть - это смерть без экрана "Возродиться,или выйти в нормальный мир".
Данный код будет довольно маленький
Код:
package me.faint.fastdead;

import org.bukkit.Bukkit;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.PlayerDeathEvent;
import org.bukkit.plugin.java.JavaPlugin;

public class Main
  extends JavaPlugin
   implements Listener{
     @Override
     public void onEnable(){
     Bukkit.getConsoleSender().sendMessage("§6[Death] Plugin loaded!");
     Bukkit.getServer().getPluginManager().registerEvents(this, this);
     saveDefaultConfig();
     reloadConfig();
     }
     @EventHandler
     public void onDeath(PlayerDeathEvent event) {
     event.getEntity().spigot().respawn();
     }
}
Plugin.yml&Компиляция = Радость

BlockBreakEvent
Или же: Мама я придумал шахту 2.0!

Интересное название,да? Ну что же,приступаем :rolleyes:
Внимание! Тут будет 1 класс,он будет довольно большой. (Для начинающих кодеров)
Код:
package me.faint.blockmoney;

import java.util.Arrays;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.block.BlockBreakEvent;
import org.*********ventory.ItemStack;
import org.*********ventory.meta.ItemMeta;
import org.bukkit.plugin.java.JavaPlugin;

public class Main
    extends JavaPlugin
    implements Listener{
    @Override
    public void onEnable()
    {
    saveDefaultConfig();
    reloadConfig();
    Bukkit.getPluginManager().registerEvents(this, this);
    Bukkit.getConsoleSender().sendMessage(ChatColor.DARK_RED + "BlockMoney>> Plugin Load");
    }
    String s = getConfig().getString("diamond_ore");
    String s2 = getConfig().getString("gold_ore");
    String s3 = getConfig().getString("iron_ore");
    String s4 = getConfig().getString("stone");
    String gold = getConfig().getString("itemname");
    String lore = getConfig().getString("itemlore");{
    s = s.replace("&", "\u00a7");
    s2 = s2.replace("&", "\u00a7");
    s3 = s3.replace("&", "\u00a7");
    s4 = s4.replace("&", "\u00a7");
    gold = gold.replace("&", "\u00a7");
    lore = lore.replace("&", "\u00a7");}
    @EventHandler 
    public void onCrateBreak(BlockBreakEvent event) {
        Player player = event.getPlayer();
        Block block = event.getBlock();
        if(block.getType() == Material.DIAMOND_ORE) {
                player.sendMessage(s);
                ItemStack stack = new ItemStack(Material.GOLD_NUGGET, 20);
                ItemMeta im = stack.getItemMeta();
                im.setDisplayName(gold);
                im.setLore(Arrays.asList(lore));
                stack.setItemMeta(im);
                player.getInventory().addItem(new ItemStack(stack));
                player.updateInventory();
                event.setCancelled(true);
            }
            if(block.getType() == Material.GOLD_ORE) {
                player.sendMessage(s2);
                ItemStack stack = new ItemStack(Material.GOLD_NUGGET, 15);
                ItemMeta im = stack.getItemMeta();
                im.setDisplayName(gold);
                im.setLore(Arrays.asList(lore));
                stack.setItemMeta(im);
                player.getInventory().addItem(new ItemStack(stack));
                player.updateInventory();
                event.setCancelled(true);
            }
            if(block.getType() == Material.IRON_ORE) {
                player.sendMessage(s3);
                ItemStack stack = new ItemStack(Material.GOLD_NUGGET, 10);
                ItemMeta im = stack.getItemMeta();
                im.setDisplayName(gold);
                im.setLore(Arrays.asList(lore));
                stack.setItemMeta(im);
                player.getInventory().addItem(new ItemStack(stack));
                player.updateInventory();
                event.setCancelled(true);
            }
            if(block.getType() == Material.STONE) {
                player.sendMessage(s4);
                ItemStack stack = new ItemStack(Material.GOLD_NUGGET, 5);
                ItemMeta im = stack.getItemMeta();
                im.setDisplayName(gold);
                im.setLore(Arrays.asList(lore));
                stack.setItemMeta(im);
                player.getInventory().addItem(new ItemStack(stack));
                player.updateInventory();
                event.setCancelled(true);}
        }
}
Что к чему,или как это вообще устроено
Первое и наверное самое основное:

Код:
                ItemStack stack = new ItemStack(Material.GOLD_NUGGET, 5);
                ItemMeta im = stack.getItemMeta();
                im.setDisplayName(gold);
                im.setLore(Arrays.asList(lore));
                stack.setItemMeta(im);
                player.getInventory().addItem(new ItemStack(stack));
                player.updateInventory();
                event.setCancelled(true);
Наверное сделаю проще
Код:
                ItemStack имя стака для примера stack = new ItemStack(Material.Предмет, количество);
                ItemMeta im = stack.getItemMeta();
                im.setDisplayName(Имя предмета);
                im.setLore(Arrays.asList(Его описание));
                stack.setItemMeta(im);
                player.getInventory().addItem(new ItemStack(имя у нас оно было stack));
                player.updateInventory();  // обновляем инвентарь,чтобы было видно предмет
                event.setCancelled(true); // отменяем ивент,чтобы игрок не сломал блок
Теперь второе:
Config.yml:

diamond_ore: '&4[Mine] &2Вам было выдано 20 монеток'
gold_ore: '&4[Mine] &2Вам было выдано 15 монеток'
iron_ore: '&4[Mine] &2Вам было выдано 10 монеток'
stone: '&4[Mine] &2Вам было выдано 5 монеток'
itemname: '&6Монетки'
itemlore: '&4By Faint'

Вот у нас и вышла полноценная шахта! Можно додумать эту шахту,или поставить предметы на обмен через ChestCommands,ну или приклеить инвентарь.

Теперь как по мне,довольно важный ивент: PlayerInteractEvent
Название говорит само за себя!
Можно много чего с ним придумать,но я хочу cookie clicker :d
Ну что же,за работу,делать мы это будем тоже в одном классе.
Код:
package me.faint.clicker;
  
import java.util.Arrays;
import java.util.logging.Logger;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.block.Action;
import org.bukkit.event.player.PlayerInteractEvent;
import org.*********ventory.ItemStack;
import org.*********ventory.meta.ItemMeta;
import org.bukkit.plugin.java.JavaPlugin;
import net.md_5.bungee.api.ChatColor;
    
    public class Main extends JavaPlugin implements Listener{  
        public final Logger logger = Logger.getLogger("Minecraft");  
        @Override
        public void onEnable() {
           saveDefaultConfig();
           reloadConfig();
           Bukkit.getServer().getPluginManager().registerEvents(this, this);
           Bukkit.getConsoleSender().sendMessage(ChatColor.AQUA + "Cookie clicker loaded!");
        }  
        String s = getConfig().getString("message");
        String gold = getConfig().getString("cookie");
        String lore = getConfig().getString("lore");{
        s = s.replace("&", "\u00a7");
        gold = gold.replace("&", "\u00a7");
        lore = lore.replace("&", "\u00a7");}
        @SuppressWarnings("deprecation")
        @EventHandler
        public void onPlayerInteract(PlayerInteractEvent event){
            if(event.getAction() == Action.RIGHT_CLICK_BLOCK && event.getClickedBlock().getTypeId() == 35){
           Player p = event.getPlayer();
           p.sendMessage(s);
           ItemStack stack = new ItemStack(Material.COOKIE, 1);
           ItemMeta im = stack.getItemMeta();
           im.setDisplayName(gold);
           im.setLore(Arrays.asList(lore));
           stack.setItemMeta(im);
           p.getInventory().addItem(new ItemStack(stack));
           p.updateInventory();
           }
        }
    }
Все довольно просто! Кликаем по ID 35 получаем печеньку.
Config.yml:

message: '&2[&4Clicker&2] &c+ 1 печенька'
cookie: '&eПеченька'
lore: '&4By Faint'

Всем покеда,с вами был Faint.
Ах да,забыл :d Вот вам плагины:
https://drive.google.com/open?id=1B4fjuZz-9bGHhSRl7iup4t4y96E3hZ8t [Жмяк]
 
Последнее редактирование:
Кто-то еще делает цветные сообщения посредством реплейса?
entity.spigot().respawn()...
А если я пишу под cb?
 
Прежде, чем писать свои стартапы, читай уже созданные. Бывает очень полезно.
Спасибо конечно,но смысл. Убрать реплейс,и поставить знак §,скоротит на 10 строк,а гемора от этого больше.
 
Смысл начинать учить java с букита? Полное говно ведь будете писать как код выше. Так-то вообще намного получше стартапы в которых все объясняется, а с этого "стартапа" ничего не выйдет, тут как бы два варианта: получится говнокодер, которое будет это все говнокодить все это без абстракции и в одном классе как у тебя, или же чувак вообще ничего не поймет
 
При загрузке плагина в конфиге могут быть изменения,вот он и перезагружает.

Вообще-то при включении плагина конфиг грузится автоматом, перезагружать его сразу после включения не надо
 
Может, раньше я бы и ничего не сказал, но этот туториал не очень поможет новичкам:
1) Новички обычно не понимают смысла кода (он написал, оно заработало! Магия!), и копируют его. Это значит, что если им надо будет написать что-то другое, все их "знания" будут больше неактуальными.
2) Туториалов на рубаките такого типа достаточно.
3) В любом случае чтобы писать реально полезные плагины, джаву надо учить и понимать код. Тогда и смысла в уроках нет. Не знаю, есть ли полная русская документация по бакиту, но это было бы гораздо полезнее.
4) У тебя самого код плохой. Новички, переписывающие этот код, будут использовать его же. Потом им будет проблематичнее отойти от привычки так писать.
5) На скринах мало что обьяснишь новичкам. Им и видео не всегда понятны.

Иронично писать это, осознавая то, что я занимался этим-же)

Но вот научить пользоваться конфигом - неплохо для новичков. Но тогда надо обьяснять больше именно про него.
Тем более, без говнокода.
 
*facepalm*,я не юзаю его потому-что не вижу в этом смысла.
А смысл было писать, что ты это не юзаешь? Мог бы написать: ВНИМАНИЕ Я НЕ ЮЗАЮ ЗДЕСЬ ПАКЕТ CONCURENT ПОТОМУ ЧТО НЕ ВИЖУ СМЫСЛА. Смысл было это писать?
 
Коротко о нашем юном тру-программисте:
Все началось с того, что я в группе дискорда демонстрировал новых мобов на своем сервере с модификациями. Этот пацан подключился к дискорду, и начал нести хyйню (выeбываться) про декомпильни клиент, там есть 3D. А потом вообще утверждал, что используя InventoryClickEvent в бакките - можно изменить интерфейс инвентаря игрока. Потом стал нести хyйню про то, что InventoryType.CHEST позволяет изменить интерфейс инвентаря.
Если честно, я ржал до слез эти 30мин тыкания его носом в документацию)) Особенно тогда, когда он предложил использовать ивент, отвечающий за отслеживание нажатий игрока в инвентаре для отрисовки GUI))
2017-11-12.1510454294.png

2017-11-12(1).1510454484.png

2017-11-12(2).1510454528.png

2017-11-12(4).1510454599.png

2017-11-12(5).1510454841.png

2017-11-12(6).1510454883.png

2017-11-12(7).1510454907.png
 
Последнее редактирование:
"Bukkit.getConsoleSender().sendMessage("§6[Joiner] Plugin loaded!");"
Логгеров для лохов, Bukkit.getConsoleSender() для пацанов!11111(Примерно так я вижу автора этой темы)
Коротко о нашем юном тру-программисте:
Все началось с того, что я в группе дискорда демонстрировал новых мобов на своем сервере с модификациями. Этот пацан подключился к дискорду, и начал нести хyйню (выeбываться) про декомпильни клиент, там есть 3D. А потом вообще утверждал, что используя InventoryClickEvent в бакките - можно изменить интерфейс инвентаря игрока. Потом стал нести хyйню про то, что InventoryType.CHEST позволяет изменить интерфейс инвентаря.
Если честно, я ржал до слез эти 30мин тыкания его носом в документацию)) Особенно тогда, когда он предложил использовать ивент, отвечающий за отслеживание нажатий игрока в инвентаре для отрисовки GUI))
2017-11-12.1510454294.png

2017-11-12(1).1510454484.png

2017-11-12(2).1510454528.png

2017-11-12(4).1510454599.png

2017-11-12(5).1510454841.png

2017-11-12(6).1510454883.png

2017-11-12(7).1510454907.png
Засунь под спойлер картинки, плиз)
 

Поделиться этой страницей

Назад
Верх