Bukkit plugins zoeken en schrijven

Door Dreeass gepubliceerd op Sunday 12 August 23:33

Bukkit

Zou je graag je eigen Bukkit plugins willen maken, maar weet niet hoe het moet? Of ben je op zoek naar een plugin, maar je hebt geen idee hoe je moet beginnen of waar je moet zoeken? Lees dan even deze pagina door, hier wordt alles uitgelegd over het zoeken van een plugin tot het zelf schrijven van een plugin.

Op het einde van elk onderdeel, zal ik een link plaatsen waar je naartoe kan gaan om de code te kopieëren en eventueel te gebruiken in je eigen project.

Het zoeken van een plugin
Ga naar BukkitDev en daar kan je de zoekfunctie gebruiken. Typ daar een kernwoord in van de plugin die je zoekt en klik op enter. Voor dit voorbeeld gebruikt ik het kernwoord 'Protection' omdat ik op zoek ben naar een plugin die mijn kisten kan beveiligen.

Je ziet dan nog 2 mogelijkheden bij het zoeken: Scope en Site. Voor site zal het automatisch op Bukkit.org only staan, maar bij scope willen we Projects only en daarna klikken we nogmaals op Search Results.

L6qKj.png

eIuvW.pngBij elk resultaat zien we de naam, een beschrijving, de auteur(s) en de datum van de laatste update. Ook zien we het woord dat we hebben gezocht gefluoresceerd staan.

Lees bij sommige plugins de beschrijving en kijk wat je interesseert. Wat mij nu interesseert is LWC. Het heeft misschien niet echt zo'n goede naam, maar het heeft een goede reputatie en de beschrijving past bij wat ik zoek.

fIAQN.png

 Na erop geklikt te hebben kom ik op de pagina van de plugin LWC. Op die pagina staat zowat alle informatie die je nodig hebt. Hier zijn alvast een paar begrippen/namen die je zou moeten kennen:
Klik op me op me te vergroten!
  • Developer build: een versie van de plugin die in ontwikkeling is, maar deze kan bugs bevatten omdat hier meestal nieuwe functies inzitten die nog not optimaal werken.
  • IRC: Internet Relay Chat, een online chat die je kan joinen. Hiervoor moet je een gebruikersnaam ingeven, maar een wachtwoord is optioneel.
  • Github: Een git repository website, een website die in staat is om mensen te laten samen werken een projecten via gits, als je hier meer over wilt te weten komen, kan je naar de wiki surfen..
  • Ticket: Je kan een ticket insturen waarin je een bug beschrijft of waarin je een voorstel doet aan de maker. Niet alle tickets zijn gemaakt voor voorstellen, sommige hebben een vast formulier die je moet invullen voor bugs.
 Nu ook wat meer informatie over de feiten van de plugin:
  • Date created: De datum waarop de plugin werd uitgegeven.
  • Categories: De categorieën waartoe de plugin tot behoort, alle categorien kun je hier bekijken.
  • Last update: De datum waarop de plugin het laatst geüpdate werd, dus de datum waarop het laatste bestand werd geüpload.
  • Development stage: Het stadium van ontwikkeling waarin de plugin verkeerd, Alpha, Beta, Release en Mature. Alpha en Beta ken je waarschijnlijk al, maar release is dat hij uitgegeven is en mature is dat hij al een tijdje is uitgegeven en dat hij volledig functionaliteit heeft.
  • Language: In welke talen de plugin zoal beschikbaar is als je hem download.
  • License: De licentie waaronder de plugin valt, dit kunnen verschillende licenties zijn. Van opensource tot alle rechten voorbehouden.
  • Curse link: De link van de plugin op de Curse website.
  • Downloads: Hoeveel maal de plugin al is gedownload.
  • Recent files: De recentste 5 upgeloade bestanden, deze worden in de volgorde ontwikkelings stadium, Naam, Versie weergegeven. Uiteraard is het ontwikkelings stadium afgekort naar de eerste letter.

Als je de plugin nu wilt downloaden, kun je op 'Downloaden' klikken en dan zie je de changelog, wat staat voor veranderingslogboek, samen met de download van het laatste bestand. Als je een eerdere versie wil downloaden, dan kan je bij de info over de plugin het bestand aanklikken dat je wilt downloaden.



Zelf een plugin schrijven

Vooraleer je je eigen Bukkit plugin wilt maken moet je Java kennen tot op een redelijk niveau, je kan hierheen gaan om Java te leren. In die afspeellijst wordt er ook uitgelegd hoe je Eclipse installeert, hier gebruik ik Eclipse en niet NetBeans of een ander programma. Je moet ook Java 6 (1.6) op je computer geïnstalleerd hebben, dit wordt later uitgelegd. Ook raad ik je aan om alles wat je gebruikt in je project in één map op te slaan. Ook heb ik op het einde van ieder onderdeel één of meerdere spoilers waarin de code staat gegeven die je kan kopieëren. 


LWhmA.png
4WrMs.pngMaak een Java project met een package en een class, zelf gebruik ik de class Main altijd. Je hebt een main/hoofd class nodig bij Bukkit die alles regelt bij het opstarten, afsluiten... van de plugin. Daarna doe je rechtermuisknop op je Java project -> Java Build Path en klik op de Libraries tab. Selecteer JRE System Library [JavaSE-1.X] en klik Edit..., selecteer Alternate JRE en uit de lijst kies je jre6 en niet jre7 of lager dan jre6. Als jre6 niet in de lijst staat, klik je op Installed JREs... Dan op Add... -> Standard VM -> Directory... en ga naar Program Files of Program Files(x86) daarna naar Java en selecteer jre6 en klik op Ok en dan op Finish. Selecteer dan jre6 in de lijst en klik je weer Finish bij het venstertje van Edit Library. (Sluit het venster van Eclipse nog niet!)


Ga nu naar dl.bukkit.org, klik op Alternate Versions, selecteer Bukkit bovenaan en download de laatste Recommended Build. Ga dan weer naar Eclipse en klik op Add External JARs..., navigeer naar je Bukkit Recommended Build en dubbelklik erop.

Ga nu naar Java Compiler, kruis bovenaan Enable project specific settings aan en bij het eerste dropdown menu kies je 1.6. En kruis Use default compliance settings aan. Daarna klik je op OK.

Je vraagt je nu waarschijnlijk af waarom we dit allemaal hebben gedaan, ik leg het je even uit. Bukkit draait op de 6de en de 7de versie van Java, maar omdat Java 7 nog in de Beta versie zit, heeft nog niet iedereen Java 7 en krijgt men daarom een error als je je project samenstelt met Java 7. Als je een plugin maakt die je niet publiek wilt maken, over een server beschikt met Java 7 en je wilt functies van Java 7 gebruiken, dan en alleen dan raad ik je aan om Java 7 te gebruiken.



AHcRz.pngAls je dit eenmaal hebt gedaan, ben je klaar voor het coderen. Hierbij vermeld ik niet steeds dat je het nodige moet importeren, maar je moet altijd bukkit.org importeren en geen andere, behalve als je de basicfuncties van Java gebruikt. De mainclass moet natuurlijk Bukkit gebruiken en daarom gebruiken we extends JavaPlugin bij onze class. Dat wordt dan: public class Main extends JavaPlugin { }


Een plugin voor Bukkit heeft een paar basis methodes nodig die hij uitvoert als de plugin start en aflsuit. Hiervoor gebruiken we de public voids onEnable() en onDisable() die geen argumenten nodig hebben. Voor deze methodes moet je ook @Override toevoegen.

wWNy4.png

Om iets aan de console te loggen heb je natuurlijk een logger nodig, deze is als volgt:

public Logger log = Logger.getLogger("Minecraft");

Je gebruikt deze dan als volgt: log.info("Hallo!");, dit zal dan het bericht Hallo! naar de console verzenden. Dit kan nuttig zijn voor debuggen en voor informatie. Je hoeft niet een bericht te verzenden als je plugin wordt geactiveerd, dit wordt al automatisch door Bukkit gedaan.


oYgBJ.png


Als je een aparte class wilt maken en vanuit die class non-static methoden en andere gebruiken, dan moet je een constructor gebruiken. Veel ga ik je niet vertellen over de constructor omdat je dat al zou moeten weten. Mits je meer informatie wilt hebben heb ik hier een filmpje voor je die meer uitleg geeft over de constructor. Maar mijn constructor ziet er alvast zo uit:

hfZiq.png



Vergeet niet dat als je een mainclass hebt die niet Main heet, dan moet je dat aanpassen. Ook Voorbeeld is de naam van de class waarin de constructor staat, dat moet je ook niet vergeten aanpassen. Maar Eclipse zal je daarbij wel helpen.

57Mue.png


Ik ga je zeggen hoe er een commando wordt uitgevoerd in een andere class omdat als je elk commando in de mainclass gaat plaatsen, gaat het onoverzichtelijk worden. Om te zeggen wat je er mee gaat doen, moet je eerst get commando ophalen d.m.v. de getCommand(String); methode, de String is dan hetgeen dat je achter je / plaatst. getCommand("voorbeeld"); zal actief zijn als ik /voorbeeld typ. Nu moeten we nog zeggen wat er moet gebeuren en dat doen we m.b.v. setExecutor(class);, dat wordt dan getCommand("voorbeeld").setExecutor(new Voorbeeld(this)), die this is nodig voor de constructor. Je moet zeggen tegen de constructor: Hier is de informatie, kom maar halen! Maak nu ook de class Voorbeeld aan, we komen hier dan zo op terug. (Je kan dit allemaal doen door er over de gaan met je muis, maak dat je de constructor en de public boolean onCommand(...) hebt.)


mVdCt.png


Eenmaal we klaar zijn in de mainclass maken we een nieuw bestand aan in ons project en niet in onze package of src, noem het plugin.yml. Wat je hier allemaal moet inschrijven staat hier uitgebreid beschreven, het is teveel om hier allemaal nogmaals te schrijven en daarom vind ik het beter dat ik hier gewoon de vereisten hier schrijf. De vereisten zijn een naam voor je plugin (name), een versie (version), de plaats waar de mainclass zich bevindt (main) en wij hebben ook nog commands nodig omdat we commando's hebben toegeovoegd aan onze plugin en Bukkit moet ze herkennen. Om je plugin.yml snel en gemakkelijk samen te stellen, kun je ook de plugin.yml generator van Dinnerbone gebruiken. Hierbij moet je dan een bestandje downloaden en gebruik enkel de plugin.yml die het bevat.

Nu moeten we de class voor het command nog schrijven, dus open je command class en wijzig de onCommand boolean naar het volgende:

public boolean onCommand(CommandSender sender, Command cmd, String commandLabel, String[] args) {...}, dit maakt het wat gemakkelijker om de argumenten te herkennen.


oRPhv.png

Wat je altijd moet doen bij een commando is kijken of de zender ervan de console is of een speler, dit kun je nagaan door te kijken of de CommandSender sender tot het Player object behoort. Als je dit niet doet en functies uitvoert die voor de speler bestemd zijn, kun je enorm veel errors krijgen als de console het uitvoert.


Om te kijken of de speler een speler is of niet, moet je nagaan of de sender die tot het object CommandSender hoort ook tot het object Player behoort. Met behulp van een if statement is dat een makkie, gebruik (sender instanceof Player) als je een argument. Dit zal true geven als het een speler is en false als het niet een speler is. Hierbij gebruik ik ook een else statement, maar je kan ook de kijken of de sender geen speler is en dan eventueel iets doen en de command stoppen. (return true/false;)

Doordat we een constructor gebruiken, kunnen we functies, variabelen en methoden van de mainclass gebruiken als we plugin. ervoor plaatsen. Bijvoorbeeld plugin.log.info("Hallo, ik ben een speler!"); zal "Hallo, ik ben een speler!" naar de console sturen.


BIooM.png

Om een bericht naar de speler te sturen of iets anders waar je een speler voor nodig hebt declareer je eerst het object Player. Player player = (Player)sender;, hierbij zeg je dus het volgende: Ik wil een Player object genaamd player aanmaken en die moet gelijk zijn aan de zender van het commando, maar je moet deze aanzien als een Player. Dus alle functies voor het object Player zijn hier van toepassing. Probeer nu maar eens player. in te typen en je krijgt een waaier aan mogelijkheden wat je allemaal met het object Player kan doen. (Tip: Je kan return false; or return true; doen als je de boolean wilt stoppen, dit kan handig zijn om te kijken of de speler de permission node heeft. Zo niet, stop het en stuur hem een bericht.)


Vf0yN.png

Vooraleer je aan listeners kan beginnen, moet je weten wat een listener doet. Een listenerclass bevat een tal van events, een event is iets dat wordt aangehaald als er iets gebeurd. Bijvoorbeeld het event PlayerMoveEvent zal worden aangehaald als een speler beweegt. Je kan daar vanalles mee doen zoals de persoon een bericht sturen dat hij beweegt, al zou ik dit niet aanraden. Want dan krijgt de persoon de hele tijd een bericht en zo wordt zijn/haar chat gespamd. Waarvoor dit misschien wel handig kan voor zijn is als de persoon in de lijst van afk personen staat, dat hij niet kan bewegen tot wanneer hij/zij uit die mode gaat. Nu je weet wat een event is en wat je ermee kan aanvangen, is het tijd om te beginnen.

Eerst moet de listenerclass geregistreerd worden aan de mainclass en dat doe je als volgt.


Je ziet dat ik de events van de listener heb geregistreerd bij de pluginmanager in de mainclass door het aangemaakte object playerListener van het objecttype Listener aan te geven en de mainclass aan de duiden als de hoofdklas (daar staat die this voor). Ook heb ik de listenerclass PlayerListener genoemd, omdat ik in die listener alleen de events van de spelers schrijf. Het is het best dat je 2 of zelfs 3 verschillende listeners hebt, zodat je orde hebt. Bijvoorbeeld 1 voor de spelers (PlayerListener), 1 i.v.m. de blokken (BlockListener) en 1 i.v.m. mobs (MobListener). Meestal gebruik ik er 2 omdat de mobs samenhangen met spelers. Ze worden meestal aangevallen door spelers en daar kan je dan wat mee doen. Het is dan irritant om heel de tijd van class de wisselen in Eclipse.

Elk event is een eigen object, want de void heeft hierbij het object PlayerMoveEvent nodig en noemt het event om het later te gebruiken. Wat ik zoal ga doen hier is als de speler tot de lijst afkPlayers behoort, die ik zo zal aanmaken, dat de speler een bericht krijgt als hij probeert te bewegen en dat hij naar zijn vorige locatie wordt geteleporteerd.


We doen dit als volgt:

Maak de ArrayList afkPlayers aan in je mainclass die het object Player moet bevatten.
public ArrayList afkPlayers = new ArrayList();
Kijk of de lijst de speler die het event uitvoerd bevat.
@EventHandler
public void onPlayerMove(PlayerMoveEvent event) {
    Player player = event.getPlayer();

    if(plugin.afkPlayers.contains(player)) {
    // De lijst afkPlayers bevat de speler van dit event.
    }
}

Verkrijg de vorige locatie van de speler, teleporteer hem ernaartoe, stuur hem een bericht en beëindig de void.

@EventHandler
public void onPlayerMove(PlayerMoveEvent event) {
    Player player = event.getPlayer();

    if(plugin.afkPlayers.contains(player)) {
        Location from = event.getFrom(); // Verkrijg de vorige locatie

        player.teleport(from); // Teleporteer de speler
        player.sendMessage("Je bent afk, je kan dan niet bewegen."); // Stuur de speler een bericht
        return; // Beëindig de void
    }
}




Als je iets fout ziet, suggesties hebt of het erg leerzaam vindt, hoor ik het graag!

Reacties (0) 

Voordat je kunt reageren moet je aangemeld zijn. Login of maak een gratis account aan.