Skript: Tworzenie rozszerzeń

Z skript.pl wiki
Skocz do: nawigacja, szukaj


Wstęp[edytuj]

W pluginie Skript poza podstawowymi wyrażeniami, istnieją także dodatki. Dzięki nim ten przewspaniały język zyskuje nowe możliwości, które nie są domyślnie wbudowane (przykładem mogą być lambdy w skQuery). W tym poradniku postaram się mniej-więcej wytłumaczyć, jak takowy dodatek napisać.

Dodanie biblioteki[edytuj]

W celu uzyskania możliwości napisania takowego dodatku, należy dodać bibliotekę (tutaj - plugin Skript) do naszego repozytorium. W zależności od IDE, można to dodać na różne sposoby. W poniższym przykładzie, do tego użyje Mavena:

<repository>
    <id>njol-repo</id>
    <url>http://maven.njol.ch/repo/</url>
</repository>
<dependency>
    <groupId>ch.njol</groupId>
    <artifactId>skript</artifactId>
    <version>2.2-SNAPSHOT</version>
    <scope>provided</scope>
</dependency>

CookieAddon - Klasa główna[edytuj]

Dobrze, stwórzmy sobie klasę główną projektu. W moim przypadku klasa nazywa się CookieAddon, a jej kod wygląda tak:

import org.bukkit.plugin.java.JavaPlugin;

public class CookieAddon extends JavaPlugin {

    @Override
    public void onEnable() {

    }

}

Wszystkie dalsze instrukcje będziemy umieszczać w metodzie onEnable.
Pierwszą rzeczą jaką musimy zrobić, jest wykrycie czy plugin Skript jest na serwerze i wyświetlenie odpowiedniego komunikatu jeśli go nie będzie.

if (getServer().getPluginManager().getPlugin("Skript") == null) {
    getLogger().log(Level.SEVERE, "Plugin Skript nie zostal wykryty");
    setEnabled(false); /* Jeśli twój plugin jest tylko dodatkiem do Skripta - wyłącz go, aby administrator widział go w /plugins na czerwono i wiedział że coś jest nie tak. */
    return;
}

Czasem zdarza się jednak, że nasz dodatek nie zostanie uruchomiony zaraz przy starcie serwera, a Skript pozwala na rejestrowanie dodatków tylko i wyłącznie przy włączeniu serwera. Można się przed tym zabezpieczyć następującym kodem:

if (!Skript.isAcceptRegistrations()) {
    getLogger().log(Level.SEVERE, "Wystąpił błąd podczas rejestracji dodatku.");
    setEnabled(false);
    return;
}

Po spełnieniu odpowiednich warunków, plugin przechodzi weryfikację poprawnie. Jednak co teraz? Należy podpowiedzieć Skriptowi, że chcemy zarejestrować takowy dodatek:

Skript.registerAddon(this);

CookieEffect - klasa efektu[edytuj]

Po wykonaniu powyższych kroków, pora na stworzenie pierwszego elementu naszego dodatku. Na potrzeby tego poradnika, stworzymy efekt który daje ciastko dla każdego gracza, oraz wysyła wiadomość (jeśli takowa zostanie wprowadzona).
W tym momencie składnia tego wyrażenia powinna wyglądać np. tak: .cookies{[%string%]};
Po obmyśleniu działania danego wyrażenia i składni, pora przejść do działania. Stwórz klasę o nazwie CookieEffect rozszerzającą klasę Effect, tak jak na poniższym przykładzie:

import ch.njol.skript.lang.Effect;
import ch.njol.skript.lang.Expression;
import ch.njol.skript.lang.SkriptParser;
import ch.njol.util.Kleenean;
import org.bukkit.event.Event;

public class CookieEffect extends Effect {

    @Override
    protected void execute(Event e) {
        
    }

    @Override
    public String toString(Event e, boolean debug) {
        return null;
    }

    @Override
    public boolean init(Expression<?>[] exprs, int matchedPattern, Kleenean isDelayed, SkriptParser.ParseResult parseResult) {
        return false;
    }

}

Oto rezultat rozszerzenia klasy Effect. Jak widzimy, mamy metodę toString. Bez zwlekania, zróbmy tak, by nie zwracała nulla. Przykładowo zamiast null, można zwrócić getClass().getName();

@Override
public String toString(Event e, boolean debug) {
    return getClass().getName();
}

Teraz musimy w jakiś sposób wprowadzić dane. Do tego posłuży nam klasa Expression<T>, oraz tablica Expression<?>[], z metody init.

@Override
public boolean init(Expression<?>[] exprs, int matchedPattern, Kleenean isDelayed, SkriptParser.ParseResult parseResult) {
    this.stringExpression = (Expression<String>) exprs[0];
    return false;
}

Pewnie teraz się zapytasz, dlaczego this.stringExpression = (Expression<String>) exprs[0];<code>. Odpowiedź prosta. Przyjrzyjmy się jeszcze raz składni naszego efektu: <code>.cookies{[%string%]};.
Jak pewnie widać, element %string% jest pierwszy, i jedyny w tej składni. Więc to naturalne, że pobierzemy zerowy element z tablicy Expression<?>[], ponieważ w Javie liczy się od zera.
Teraz przechodzimy do zdefiniowania działania efektu. W tym momencie, musimy pobrać zawartość właściwości, o nazwie stringExpression i wykonać odpowiednie akcje:

@Override
protected void execute(Event e) {
    String message = stringExpression.getSingle(e);

    for (Player player : Bukkit.getOnlinePlayers()) {
        player.getInventory().addItem(new ItemStack(Material.COOKIE, 1));
        player.updateInventory();
    }

    if (message != null) {
         Bukkit.broadcastMessage(ChatColor.translateAlternateColorCodes('&', message));
    }
}

Pozostało tylko zarejestrować efekt w klasie głównej, na końcu metody onEnable:

Skript.registerEffect(CookieEffect.class, ".cookies{[%string%]};");

Efekt końcowy[edytuj]

Klasa główna (CookieAddon)[edytuj]

import ch.njol.skript.Skript;
import org.bukkit.plugin.java.JavaPlugin;

import java.util.logging.Level;

public class CookieAddon extends JavaPlugin {

    @Override
    public void onEnable() {
        if (getServer().getPluginManager().getPlugin("Skript") == null) {
            getLogger().log(Level.SEVERE, "Plugin Skript nie zostal wykryty");
            setEnabled(false);
            return;
        }

        if (!Skript.isAcceptRegistrations()) {
            getLogger().log(Level.SEVERE, "Wystąpił błąd podczas rejestracji dodatku.");
            setEnabled(false);
            return;
        }

        Skript.registerAddon(this);
        Skript.registerEffect(CookieEffect.class, ".cookies{[%string%]};");
    }

}

Klasa efektu (CookieEffect)[edytuj]

import ch.njol.skript.lang.Effect;
import ch.njol.skript.lang.Expression;
import ch.njol.skript.lang.SkriptParser;
import ch.njol.util.Kleenean;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.Event;
import org.bukkit.inventory.ItemStack;

public class CookieEffect extends Effect {

    private Expression<String> stringExpression;

    @Override
    protected void execute(Event e) {
        String message = stringExpression.getSingle(e);

        for (Player player : Bukkit.getOnlinePlayers()) {
            player.getInventory().addItem(new ItemStack(Material.COOKIE, 1));
            player.updateInventory();
        }

        if (message != null) {
            Bukkit.broadcastMessage(ChatColor.translateAlternateColorCodes('&', message));
        }
    }

    @Override
    public String toString(Event e, boolean debug) {
        return getClass().getName();
    }

    @Override
    public boolean init(Expression<?>[] exprs, int matchedPattern, Kleenean isDelayed, SkriptParser.ParseResult parseResult) {
        this.stringExpression = (Expression<String>) exprs[0];
        return false;
    }

}