Witajcie, znam się troszkę na tym, więc postanowiłem się nią podzielić, miłej lektury, mam nadzieje, że chociaż trochę pomogę, nie uważam się za jakiegoś eksperta, więc mogą być błedy, za ich wskazanie dzięki wielkie.
Część 1 - przygotowujemy środowisko:
Do naszego pisania będziemy używać programu pt. NetBeans (dzięki Throkowi za wskazanie go), jest on dostępny na tej stronie:
By zobaczyć linki musisz się zalogować lub zarejestrować
Pobieramy program (NetBeans IDE 7.x.x) i instalujemy, nie ma tutaj co pokazywać, przechodzimy przez instalacje i odpalamy program, naszym oczom ukaże się interfejs:
Prosty i ładny, nic więcej.
Pamiętajcie, nigdy nie usuwajcie swoich starych projektów, dosyć często się do nich wraca!
I to tyle moi drodzy, jeśli chodzi o środowisko, teraz zostało jeszcze pobrać plik bukkit.jar (nie craftbukkit!) z którego będziemy importować wszelkie rzeczy, robimy to tutaj:
By zobaczyć linki musisz się zalogować lub zarejestrować
Wybieramy Alternative Version -> Bukkit i ostatnią, stabilną wersje.
(Co do stabilności, można betę, tylko czerwonej nie polecam )
I...to tyle, nie trzeba jak w przypadku eclipse nic zmieniać, jeśli chodzi o instalacje środowiska wszystko mamy za sobą
Część 2 - skład pluginu
Zanim zabierzemy się do pracy nad naszą pierwszą wtyczką, warto by poznać składnię javy, bo jeśli nie mieliście z nią styczności, to podstawa, tutaj ogólny skład:
package me.dragon.nauka; //nasza paczka, czyli folder z klasami import java.util.logging.Logger; import org.bukkit.command.Command; import org.bukkit.command.CommandSender; import org.bukkit.plugin.java.JavaPlugin; public class MeDragonNauka extends JavaPlugin { //nawias klamrowy, tworzy cialo danego elementu static final Logger log=Logger.getLogger("Minecraft"); //ta oto linijka mówi, gdzie będzie konsola //Tu będzie wszystko co wykonywał plugin @Override //to jest potrzebne, lecz dodwane jest automatycznie public void onEnable(){ //ta o to metoda mówi co plugin ma zrobić podczas włączania serwera, np. wysyla wiadomosc do konsoli //tu coś jest } @Override public void onDisable(){ //tutaj metoda mowi, co ma robic plugin podczas wylaczania serwera log.info("Wylaczone"); //daje inf. w konsoli, ze jest wylaczony } @Override public boolean onCommand(CommandSender sender, Command command, String commandLabel, String[] args){ //to metoda, którą stosujemy gdy chcemy zainicjować komendy np. if(command.getName().equalsIgnoreCase("przyklad")){ //tak inicjujemy komende, w "" jest nazwa, pozniej wyjasnie sender.sendMessage("Przyklad"); //ta linika odpowiada za wyslanie wiadomosci do gracza, ktory wpisal komende } return false; //tu mowimy jave, zeby nic nie zwracala w przypadku braku komendy, bez tego bedzie crash } }
Wszystko, co powinniście wiedzieć na początek, teraz zrobimy nasz pierwszy, prosty plugin
Część 3 - Na początek coś banalnego
Tworzymy projekt
File > New Project > Java > Java Application
Tutaj nazywamy nasz projekt "Nauka", odznaczamy Use dedicated Folder oraz Create Main Class, Klikamy Finish,
brawo, zrobiłeś swój pierwszy projekt
Jeśli wszystko jest dobrze, powinno to wyglądać tak:
Teraz tworzymy nową paczkę, kliamy na Source Packages > New > Package, nazywamy ją me.Nauka
T dobrze, przejdźmy do stworzenia naszej klasy, klikamy prawym na naszą Naukę i > New > Java Class, nazywamy ją Nauka,
ukazuje się nam coś takiego:
/* * To change this template, choose Tools | Templates * and open the template in the editor. */ package me.Nauka; /** * * @author Igorek */ public class Nauka { }
Zostawiamy tylko public class Nauka i package me.Nauka, reszta sru do kosza, i teraz weźmy się do roboty, do
public class Nauka {
zmieniamy na
public class Nauka extends JavaPlugin {
Hmm...wyskakuje błąd? I słusznie, bo nie importowaliśmy bibliotek bukkita, robimy to klikając prawym na Libraries > Add Jar/Folder i znajdujemy nasz bukkit.jar, oraz go wrzucamy. Teraz możemy importować JavaPlugin, jak widać, robi się to klikając na żaróweczkę, i import, pamiętajcie, ta żarówka to wasz przyjaciel, pokazuje wam wskazówki, do których często się stosujemy, więc improtujemy i między nawiasami klamrowymi przepisujemy to (przepisujemy, nie kopiujemy, bo to nie ma sensu przy kopiowaniu):
static final Logger log=Logger.getLogger("Minecraft");
Jest to linijka, która informuje, gdzie będą zapisywane logi, czyli wskazuje po prostu pluginowi konsolę, można i bez tego, ale nie mówię, że będzie działać poprawnie.
Teraz spacja miejsca i przepisujemy:
public void onEnable(){ log.info("Plugin testowy wlaczony"); }
Teraz odrobinę wyjaśnienia, metoda onEnable mówi pluginowi, co ma zrobić podczas włączenia serwera, tutaj za pomocą log.info("tekst") wysyłamy informacje, że plugin zostaje włączony
WAŻNE! na końcu każdej linijki w ciałach metod dajemy ";", nie zapominajcie o tym!
Teraz możemy przekopiować poprzednie tylko zmieniamy onEnable na OnDisable i linijke log.info na "Plugin testowy zostal wylaczony",
ta metoda mówi pluginowi, co ma zrobić podczas wyłączenia serwera.
Dopiska: Dajemy overry, słuchamy się żarówki
--
I teraz najciekawsze, czyli metoda onCommand, odpowiada ona za deklaracje komend, więc do roboty, przepisujemy to:
public boolean onCommand(CommandSender sender, Command command, String commandLabel, String[] args){ }i dajemy return staticoś
Ta magiczna i długa linijka deklaruje wszystko, co do życia potrzebne, teraz w środeczek dajemy(między return a tym):
if(command.getName().equalsIgnoreCase("przyklad")){ sender.sendMessage("To jest wiadomosc"); return true; }
Teraz w woli wyjaśnienia:
if(command.getName.equalsIgnoreCase("przyklad")){
mówi pluginowi, że jeśli gracz wpisze /przyklad to coś, equalsIgnoreCase jest po to, by sprawdzalo, czy to wlasciwe slowo, getName pobiera nazwę, a w nawias dajemy komendę, no i nawias klamrowy otwierający ciało komendy
sender.sendMessage("To jest wiadomosc");
Mówi plugnowi, że ma wysłać do tego, co wysłało komendę wiadomość w nawiasach, pokaże wam się to w przykladach, jeśli wpiszecie samo sender. (netBeans ma taką fajną fukcje, że pokazuje sugestie ) o i nasze ; na końcu
return true;
}
Mówi pluginowi, że ma zwrócić powyższe no i zamykamy nawias klamrowy, powinno to wyglądać tak:
package me.Nauka; import java.util.logging.Logger; import org.bukkit.command.Command; import org.bukkit.command.CommandSender; import org.bukkit.plugin.java.JavaPlugin; public class Nauka extends JavaPlugin { static final Logger log=Logger.getLogger("Minecraft"); @Override public void onEnable(){ log.info("Plugin Testowy zostal wlaczony"); } @Override public void onDisable(){ log.info("Plugin testowy zostal wylaczony"); } @Override public boolean onCommand(CommandSender sender, Command command, String commandLabel, String[] args){ if(command.getName().equalsIgnoreCase("przyklad")){ sender.sendMessage("To jest wiadomosc"); return true; } return false; } }
Praktycznie, nasz plugin jest gotowy, lecz to nie wszystko, musimy stworzyć w Source package plik plugin.yml, i przepisujemy parę linijek:
name: Nauka main: me.Nauka.Nauka version: 1.0 description: Plugin do nauki commands: przyklad: description: przyklad komendyLinijka name nazywa plugin, będzie on wyświetlany z taką nazwą pod /plugins
Linijka main wskazuje klasę główną, jest to nazwanaszejpaczki.nazwaklasy
Linijka version to wersja, to się przyda później
description: Opis pluginu
commands: tutaj deklarujemy komendy
Tutaj wpisujemy nasze komendy i ich opisy, to tyle
I w tej chwili możemy skompilować nasz projekt, klikając na niego i Build
Wszystko ok? To dalej
Teraz wchodzimy w
C:\Users\Twój folder użytkownika\Documents\NetBeansProjects\Nauka\dist
Tutaj znajduje się nasz plik Nauka.jar
Teraz zróbcie sobie serwer na localhost-cie (bukkita, nie minecraft.server) - robimy go za pomocą wpisania w adres ip localhost, łączymy się także za pomocą tego.
Kreaujemy serwer i sprawdzamy czy działa...
Jak widać, wszystko jest poprawnie.
Gratuluje, stworzyłeś swój pierwszy plugin! W następnych lekcjach zabierzemy się za coś pożytecznego.
Część 4 - *Dodatek do 3* - Podwójne człony komend
if (command.getName().equalsIgnoreCase("przyklad")) //tutaj mamy właśnie deklaracje komendy { if ((args.length == 1) && (args[0].equalsIgnoreCase("przykladu"))) //tutaj każemy pluginowi zrobic cos gdy wpiszemy /przyklad przykladu { sender.sendMessage("Wpisales przyklad przykladu? Lol"); return true; } else if (args.length > 1) { sender.sendMessage(ChatColor.GOLD + "Wpisales o " + args.length + "za duzo slow!"); //a tu gdy będzie za duzo slow return true; } sender.sendMessage("Wpisales sam /przyklad...."); //a tu gdy piszemy sam /przyklad return true; } return false;
To tyle, nic skomplikowanego, można tak zrobić więcej słów, to oddaje do waszej zabawy
ZADANIA
1. Zrób plugin który reaguje na komendę /uczen oraz /uczen zly /uczen dobry, pozostawiam wam co ma robić,
Rozwiązanie podaj w komentarzu, ocenie
Część 5 - Ekwipunek gracza
W tej części skupimy się na ekwipunku, pokaże wam jak do niego coś dodać, jak dać coś na zbroję i go wyczyścić,
mała informacja - ekwipunek to taka rzecz, którą trzeba zainicjować, bo to zmienna, robimy to tak: (oczywiście w miejscu na ciało komendy):
STOP!
Tutaj napotykamy przeszkodę! Ponieważ poprzednia komenda mogła zostać wysłana z konsoli, ale ta już nie! no chyba że macie ekwipunek w cmd to powodzenia..każda komenda musi mieć tą deklarację jeśli zarządza czymś z graczem!
O to tak to powinno wyglądać
public boolean onCommand(CommandSender sender, Command command, String commandLabel, String[] args){ if(sender instanceof Player){ //deklaracja o ktorej mowa, mowi pluginowi, ze tylko player moze wyslac ta komende (Gracz) Player p = (Player) sender; if(commandLabel.equalsIgnoreCase("eq")){ //cialo komendy } } return false; }
I to tyle, teraz przejdźmy do rzeczy, tak inicjujemy zmienna ItemStack, czyli po prostu item, ktory ma być przydzielony (wszystko w ciele komendy, to zmienna lokalna, jesli zrobimy ja gdzie indziej, nie zadziała (zmienne lokalne - w obrębie danego ciała - globalne - w całtym pliku (nie paczce :I))
ItemStack japgo = new ItemStack(Material.APPLE, 1); //to 1 to ilość, liczby dajemy zawsze po przecinku i spacji
Inicjujemy zmienna pt. "japgo" ( ), zmienna to typzmiennej nazwajej = comazawierać zmienna, w woli javy
No dobrze, zaimportujmy itemstack i ta o to linijka powinna dać graczowi jabłko (Material.tusewybierasznazweitemu), ale nie, bo zmienne nie tylko inicjujemy, ale musimy ją także zadeklarować, o tak:
PlayerInventory pv = p.getInventory(); //tutaj deklarujemy ekwipunek gracza pv.addItem(japgo); //to jest linijka ktora deklaruje zmienna, pv mozna zmienic wyzej na cos innego, to po prostu ulatwienie, jak się robi więcej tego, to pomaga. W nawiasy dajemy nazwę itemstacku
I to tyle jeśli chodzi o dodawanie, teraz zróbmy czyszczenie ekwipunku:
dodajemy to:
pv.clear();Można też usuwać pojedyńcze itemy:
pv.remo(itemstack);
tyle
To na koniec, itemy na zbroje:
wklejamy z powrotem uwczesne, i inicjujemy 4 typy itemów:
ItemStack buty = new ItemStack(Material.DIAMOND_BOOTS, 1); ItemStack gacie = new ItemStack(Material.DIAMOND_LEGGINGS, 1); ItemStack klata = new ItemStack(Material.DIAMOND_CHESTPLATE, 1); ItemStack kapelusz = new ItemStack(Material.DIAMOND_HELMET, 1);
Zbroja jak widać, teraz robimy eq i takie cuś:
PlayerInventory pv = p.getInventory(); pv.setBoots(buty); pv.setLeggings(gacie); pv.setChestplate(klata); pv.setHelmet(kapelusz); return true;
pv.setNazwaCzesciZbroi ustawia nam po prostu item na danej części ciała, możemy też zrobić to z slotem, gdzie aktualnie mamy rękę:
pv.setItemInHand(tutaj daj itemstack);
Proste cnie? A jakie przydatne
Zadania
Stwórz ekwipunek wojownika, daj mu zbroje, miecz do ręki oraz łuk i stack strzał!
Stwórz czyściciela ekwipunku
6 - Hashmapy by Axer
Podczas robienia pluginu często znajdziesz się w momencie, gdzie zwykłe zmienne będą niewystarczające. Z pomocą przychodzą HashMapy.
HashMapa działa na zasadzie klucz->wartość (np. HashMap<String,String>). Za pomocą Metody put(klucz,wartość) umożliwia dodanie pary oraz sprawdzanie, co jest pod danym kluczem metodą get(klucz).
Pokażę wam zastosowanie HashMap na podstawie pluginu dającego nieśmiertelność(czyli po prostu GodMode).
Najpierw dodajemy taką linjkę na górze pod package:
import java.util.HashMap;Tworzymy HashMapę:
public static HashMap<String, Boolean> graczeGod = new HashMap();Czemu parametry String i Boolean?
String - nick gracza.
Boolean - przełącznik informujący, czy gracz ma GodMode'a.
Tworzymy komendę na goda:
@Override public boolean onCommand(CommandSender sender, Command command, String commandLabel, String[] args) { if (command.getName().equalsIgnoreCase("god")) { if (args.length == 1) { //sprawdza ilosc argumentow, w tym wypadku jeden - nick gracza if (sender.getServer().getPlayer(args[0]) != null) { //sprawdza czy dany gracz jest online Player celGracz = sender.getServer().getPlayer(args[0]); graczeGod.put(celGracz.getName(), Boolean.valueOf(true)); //wprowadza do HashMapy klucz celGracz(nick gracza) z booleanem true(przelacznik god mode) sender.sendMessage(ChatColor.AQUA + celGracz.getDisplayName() + " otrzymal tryb God!"); celGracz.sendMessage(ChatColor.GOLD + sender.getName() + ChatColor.AQUA + " wlaczyl tobie tryb God!"); } else { sender.sendMessage(ChatColor.RED + "Nie znaleziono gracza!"); } } else if (args.length > 1) { sender.sendMessage(ChatColor.RED + "Za duzo argumentow!"); } } return false; }Dobrze, mamy komendę /god, która dodaje danego gracza i przełącznik GodMode'a do HashMapy graczeGod .
Teraz rozszerzamy plugin o komendę zmieniającą boolean odpowiadający za GodMode'a w graczeGod na false, cztli komendę /ungod.
@Override public boolean onCommand(CommandSender sender, Command command, String commandLabel, String[] args) { if (command.getName().equalsIgnoreCase("god")) { if (args.length == 1) { //sprawdza ilosc argumentow, w tym wypadku jeden - nick gracza if (sender.getServer().getPlayer(args[0]) != null) { //sprawdza czy dany gracz jest online Player celGracz = sender.getServer().getPlayer(args[0]); graczeGod.put(celGracz.getName(), Boolean.valueOf(true)); //wprowadza do HashMapy klucz celGracz(nick gracza) z booleanem true(przelacznik god mode) sender.sendMessage(ChatColor.AQUA + celGracz.getDisplayName() + " otrzymal tryb God!"); celGracz.sendMessage(ChatColor.GOLD + sender.getName() + ChatColor.AQUA + " wlaczyl tobie tryb God!"); } else { sender.sendMessage(ChatColor.RED + "Nie znaleziono gracza!"); } } else if (args.length > 1) { sender.sendMessage(ChatColor.RED + "Za duzo argumentow!"); } }else if(command.getName().equalsIgnoreCase("ungod")) { if (args.length == 1) { //sprawdza ilosc argumentow, w tym wypadku jeden - nick gracza if (sender.getServer().getPlayer(args[0]) != null) { //sprawdza czy dany gracz jest online Player celGracz = sender.getServer().getPlayer(args[0]); graczeGod.put(celGracz.getName(), Boolean.valueOf(true)); //wprowadza do HashMapy klucz celGracz(nick gracza) z booleanem false(przelacznik god mode) sender.sendMessage(ChatColor.AQUA + celGracz.getDisplayName() + " nie ma juz trybu God!"); celGracz.sendMessage(ChatColor.GOLD + sender.getName() + ChatColor.AQUA + " wylaczyl tobie tryb God!"); } else { sender.sendMessage(ChatColor.RED + "Nie znaleziono gracza!"); } } else if (args.length > 1) { sender.sendMessage(ChatColor.RED + "Za duzo argumentow!"); } } return false; }Bardzo dobrze. Rozszerzamy funkcję o komendę /sprawdz, sprawdzającą, czy dany gracz ma włączony GodMode.
@Override public boolean onCommand(CommandSender sender, Command command, String commandLabel, String[] args) { if (command.getName().equalsIgnoreCase("god")) { if (args.length == 1) { //sprawdza ilosc argumentow, w tym wypadku jeden - nick gracza if (sender.getServer().getPlayer(args[0]) != null) { //sprawdza czy dany gracz jest online Player celGracz = sender.getServer().getPlayer(args[0]); graczeGod.put(celGracz.getName(), Boolean.valueOf(true)); //wprowadza do HashMapy klucz celGracz(nick gracza) z booleanem true(przelacznik god mode) sender.sendMessage(ChatColor.AQUA + celGracz.getDisplayName() + " otrzymal tryb God!"); celGracz.sendMessage(ChatColor.GOLD + sender.getName() + ChatColor.AQUA + " wlaczyl tobie tryb God!"); } else { sender.sendMessage(ChatColor.RED + "Nie znaleziono gracza!"); } } else if (args.length > 1) { sender.sendMessage(ChatColor.RED + "Za duzo argumentow!"); } } else if (command.getName().equalsIgnoreCase("ungod")) { if (args.length == 1) { //sprawdza ilosc argumentow, w tym wypadku jeden - nick gracza if (sender.getServer().getPlayer(args[0]) != null) { //sprawdza czy dany gracz jest online Player celGracz = sender.getServer().getPlayer(args[0]); graczeGod.put(celGracz.getName(), Boolean.valueOf(false)); //wprowadza do HashMapy klucz celGracz(nick gracza) z booleanem false(przelacznik god mode) sender.sendMessage(ChatColor.AQUA + celGracz.getDisplayName() + " nie ma juz trybu God!"); celGracz.sendMessage(ChatColor.GOLD + sender.getName() + ChatColor.AQUA + " wylaczyl tobie tryb God!"); } else { sender.sendMessage(ChatColor.RED + "Nie znaleziono gracza!"); } } else if (args.length > 1) { sender.sendMessage(ChatColor.RED + "Za duzo argumentow!"); } } else if (command.getName().equalsIgnoreCase("sprawdz")) { if (args.length == 1) { //sprawdza ilosc argumentow, w tym wypadku jeden - nick gracza if (sender.getServer().getPlayer(args[0]) != null) { //sprawdza czy dany gracz jest online final Player celGracz = sender.getServer().getPlayer(args[0]); if (graczeGod.containsKey(celGracz.getName())) { //sprawdza, czy nick gracza jest w hashmapie if (graczeGod.containsValue(Boolean.valueOf(true))) { //sprawdza, czy gracz ma tryb God sender.sendMessage(ChatColor.AQUA + celGracz.getDisplayName() + " ma tryb God."); //wysyla wiadomosc o posiadaniu trybu }else{ //jesli gracz nie ma trybu god, przechodzi tutaj sender.sendMessage(ChatColor.AQUA + celGracz.getDisplayName() + " nie ma trybu God."); //wysyla wiadomosc o nie posiadaniu trybu } }else{ //jesli gracza wcale nie ma w hashmapie, przechodzi tutaj graczeGod.put(celGracz.getName(), Boolean.valueOf(false)); //dodaje gracza do hashmapy z wylaczonym godem sender.sendMessage(ChatColor.AQUA + celGracz.getDisplayName() + " nie ma trybu God."); //wysyla wiadomosc o nie posiadaniu trybu } } else { sender.sendMessage(ChatColor.RED + "Nie znaleziono gracza!"); } } else if (args.length > 1) { sender.sendMessage(ChatColor.RED + "Za duzo argumentow!"); } } return false; }Świetnie. Teraz zostało tylko dodanie tych komend do pliku plugin.yml.
god: description: Daje goda danemu graczu. ungod: description: Zabiera goda danemu graczu. sprawdz: description: Sprawdza, czy gracz ma goda.Zapisujemy i kompilujemy. Mamy nasz plugin, jednak na razie NIE DAJE nieśmiertelności, gdyż nie ustawiliśmy Listenera(nasłuchiwacza). O Listenerach już w następnej części.
Przyszłe części wkrótce
Copyright:
Ten poradnik to moja własność intelektualna i zakazuje go kopiować bez zgody mojej, oraz przywłaszczać autora sobie
Przydatne linki:
By zobaczyć linki musisz się zalogować lub zarejestrować
- kurs Javy, polecam,By zobaczyć linki musisz się zalogować lub zarejestrować
- fora bukkitaPS:
Ten poradnik to podstawy, jak chcesz napisać drugiego bukkita, to naucz się porządnie javy i zagłęb się w biblioteki wszelakiej maści.