NimBlock Giriş yap

Eklenti grameri

specVersion 1

Bir NimBlock eklentisi kod değildir: kuralları tanımlayan, herkes için bir kez yazılmış bir Paper motoru tarafından okunup çalıştırılan bir JSON dosyasıdır. Bu sayfa, içine tam olarak ne yazabileceğini söyler ve başka hiçbir şey mümkün değildir.

Bir kural, sadece bir kural

Tüm gramer tek bir cümleye sığar: bu gerçekleştiğinde, şu koşullar sağlanıyorsa, şunu yap. Bir eklenti kurallar listesidir; bir kural bir tetikleyici, sıfır ile 20 arası koşul ve bir ile 50 arası eylemden oluşur.

Hiçbir yerde Java üretilmez, hiçbir derleme yapılmaz: sunucu, spec'i okuyan bir motor yükler. Asıl önemli olan bu özelliktir, çünkü yeni bir Minecraft sürümünün bedeli sadece bu motorda ödenir, onunla yazılmış her eklentide değil.

Bir spec'in biçimi

{
    "specVersion": 1,
    "name": "Hoş Geldin",
    "rules": [
        {
            "id": "hosgeldin",
            "name": "Hoş geldin mesajı",
            "match": "all",
            "trigger": { "type": "player.join" },
            "conditions": [
                { "type": "player.has_permission", "params": { "permission": "nimblock.vip" } }
            ],
            "actions": [
                { "type": "player.send_message", "params": { "message": "&6Hoş geldin {player}!" } }
            ]
        }
    ]
}

match, all (varsayılan) veya any değerini alır ve bir koşul "not": true taşıyabilir. enabled: false, bir kuralı etkinleştirmeden dosyada tutar.

Gramer, EBNF olarak

Aşağıdaki uç öğe (terminal) listeleri katalogdan üretilir: bunlar motorun çalıştırabildiği tanımlayıcıların ta kendisidir, elle yapılmış bir transkripsiyon değildir.

<plugin>       ::= "{" "specVersion" ":" 1 ","
                       [ "id" ":" <slug64> "," ]
                       "name" ":" <label> ","
                       [ "description" ":" <text500> "," ]
                       "rules" ":" "[" <rule> { "," <rule> } "]" "}"      (* 1..200 *)

<rule>         ::= "{" [ "id" ":" <slug32> "," ]
                       "name" ":" <label> ","
                       [ "enabled" ":" <boolean> "," ]                   (* = true *)
                       [ "match" ":" ( "all" | "any" ) "," ]              (* = "all" *)
                       "trigger" ":" <trigger> ","
                       [ "conditions" ":" "[" [ <condition>
                             { "," <condition> } ] "]" "," ]              (* 0..20 *)
                       "actions" ":" "[" <action>
                             { "," <action> } "]" "}"                     (* 1..50 *)

<trigger>      ::= "{" "type" ":" <trigger-id>   [ "," "params" ":" <params> ] "}"
<condition>    ::= "{" "type" ":" <condition-id> [ "," "not" ":" <boolean> ]
                                                 [ "," "params" ":" <params> ] "}"
<action>       ::= "{" "type" ":" <action-id>    [ "," "params" ":" <params> ] "}"

<params>       ::= "{" [ <param-name> ":" <param-value>
                       { "," <param-name> ":" <param-value> } ] "}"
<param-value>  ::= <template> | <identifier> | <integer> | <number>
                 | <boolean> | <choice>

<template>     ::= { <literal> | <variable> | <colour> }                (* 0..2000 *)
<literal>      ::= /[^{}]/ | "{{" | "}}"
<variable>     ::= "{" /[a-zA-Z][a-zA-Z0-9_]*/ "}"
<colour>       ::= "&" ( "0".."9" | "a".."f" | "k".."o" | "r" )

<identifier>   ::= /[A-Za-z][A-Za-z0-9_:.\/-]{0,63}/
<slug32>       ::= /[A-Za-z0-9_-]{1,32}/
<slug64>       ::= /.{0,64}/
<label>        ::= /.{1,64}/
<text500>      ::= /.{0,500}/

<trigger-id>   ::= "player.join"
                 | "player.quit"
                 | "player.chat"
                 | "player.death"
                 | "player.respawn"
                 | "block.break"
                 | "block.place"
                 | "command"
                 | "schedule.repeat"
<condition-id> ::= "player.has_permission"
                 | "player.is_op"
                 | "player.in_world"
                 | "player.health_below"
                 | "text.contains"
                 | "text.equals"
                 | "number.compare"
                 | "chance"
<action-id>    ::= "player.send_message"
                 | "player.send_actionbar"
                 | "player.send_title"
                 | "player.play_sound"
                 | "player.give_item"
                 | "player.give_effect"
                 | "player.heal"
                 | "player.teleport"
                 | "player.kick"
                 | "broadcast"
                 | "server.run_command"
                 | "cancel_event"
                 | "log"
                 | "delay"

Bu üretim kurallarında görünmeyen iki şey vardır, çünkü bunlar biçimle değil tutarlılıkla ilgilidir. Bir oyuncu gerektiren koşul veya eylem, ancak bir oyuncu sağlayan bir tetikleyicinin altında yazılabilir: "oyuncuyu iyileştir", "her N saniyede bir" altında bir anlam ifade etmez. Ve cancel_event yalnızca iptal edilebilir bir tetikleyicinin altında yazılabilir. İkisi de yazım sırasında reddedilir, çalışma sırasında değil.

Şablonlar

text türündeki parametreler şablondur: {player}, tetikleyicinin sağladığı değerle değiştirilir, {{ gerçek bir küme parantezi verir ve &a &l gibi renk kodları çevrilir.

Tetikleyicinin tanımadığı bir değişken, metin değil bir hatadır. Her tetikleyici neyi sağladığını bildirir (aşağıdaki listeye bak): bu listenin dışında okunacak hiçbir şey yoktur ve bir yazım hatası, oyuncuların sohbetine düşmek yerine yazım sırasında reddedilir. Bir tetikleyicinin kendi parametreleri ise şablon değildir: bunlar sunucu başlarken, henüz değiştirilecek hiçbir şey yokken okunur.

Minecraft isimleri, neyi belirttiklerine göre iki şekilde yazılır. Bir eşya, her iki yazımla da adlandırılabilir (DIAMOND_SWORD veya diamond_sword). Bir ses veya efekt ise Bukkit sabiti yerine Minecraft anahtarıyla adlandırılır (entity.player.levelup, speed): bu anahtar istemciye olduğu gibi gider ve sürümler arasında değişmeden kalır.

Gramerin izin vermediği şeyler

Kapalıdır ve bunu her şeyden önce söylemek gerekir. Katalogda yer alan yapılabilir, geri kalanı imkânsızdır ve öyle kalacaktır: keyfi Java kodu çalıştırmanın hiçbir yolu yoktur. Bu da stüdyoyu anlık kılar (derlenecek hiçbir şey yok) ve bir spec'in nereden geldiğine bakılmaksızın kurulumunu zararsız hale getirir.

Koşullar iç içe geçmez: bu, 1. sürümün bilinçli olarak kabul edilmiş bir sınırıdır, bir Boole ağacı bloklarla kötü çizilir ve all / any / not neredeyse her zaman yeterlidir. Tek çıkış kapısı, o sunucuda konsolun gücüne sahip olan, ne fazlası ne eksiği "konsol olarak bir komut çalıştır" eylemidir.

Tetikleyiciler

Bir kuralı başlatan şey ve her birinin şablonlar için sağladığı değişkenler.

player.join Bir oyuncu bağlanır

Oyuncu, dünyası yüklendikten sonra sunucuya girdiği an.

sağlar: {player} Bağlanan oyuncu, {world} Geldiği dünya

player.quit Bir oyuncu ayrılır

Oyuncu sunucudan ayrıldığı an. Hâlâ ulaşılabilir durumdadır, ama gönderilen her mesaj kaybolur.

sağlar: {player} Ayrılan oyuncu, {world} Ayrıldığı dünya

player.chat Bir oyuncu sohbete yazar iptal edilebilir

Mesaj diğer oyunculara iletilmeden önce. İptal edilebilir: bu durumda mesajı kimse görmez.

sağlar: {player} Mesajı yazan oyuncu, {world} Dünyası, {message} Yazılan mesaj

player.death Bir oyuncu ölür

Oyuncu öldüğünde, yeniden doğma ekranından önce.

sağlar: {player} Ölen oyuncu, {world} Dünyası, {killer} Sorumlu oyuncu, yoksa boş

player.respawn Bir oyuncu yeniden doğar

Oyuncu öldükten sonra oyuna geri döndüğünde.

sağlar: {player} Yeniden doğan oyuncu, {world} Yeniden doğma dünyası

block.break Bir oyuncu blok kırar iptal edilebilir

Blok yok olmadan önce. İptal edilebilir: blok yerinde kalır.

sağlar: {player} Kıran oyuncu, {world} Dünyası, {block} Blok türü (DIAMOND_ORE), {x} Bloğun X koordinatı, {y} Bloğun yüksekliği, {z} Bloğun Z koordinatı

block.place Bir oyuncu blok yerleştirir iptal edilebilir

Blok yerleştirilmeden önce. İptal edilebilir: blok yerleştirilmez.

sağlar: {player} Yerleştiren oyuncu, {world} Dünyası, {block} Yerleştirilen blok türü, {x} Bloğun X koordinatı, {y} Bloğun yüksekliği, {z} Bloğun Z koordinatı

command Bir oyuncu komut yazar

Sunucuda yeni bir komut oluşturur. ⚠️ Adı daha önce var olmayan bir komut, ancak sunucu yeniden başlatıldığında görünür: Paper yeni komut adlarını yalnızca başlangıçta kabul eder. Kuralın içeriği ise anında yeniden yüklenir.

  • name text Komut adı, eğik çizgi olmadan
  • description text isteğe bağlı Yardımda gösterilen açıklama
  • permission text isteğe bağlı Gereken izin, herkes için boş

sağlar: {player} Komutu yazan oyuncu, {world} Dünyası, {args} Komuttan sonra gelen her şey, olduğu gibi

schedule.repeat Her N saniyede bir

Kuralı sunucu çalıştığı sürece tekrarlar. Hiçbir oyuncu söz konusu değildir: yalnızca oyuncu gerektirmeyen eylemler kullanılabilir.

  • seconds integer [1..86400] Saniye cinsinden aralık

Koşullar

Filtreleyen şey. Kural başına sıfır ile 20 arası, match ile birleştirilir.

player.has_permission Oyuncunun izni var bir oyuncu gerektirir
  • permission text İzin
player.is_op Oyuncu operatör bir oyuncu gerektirir
player.in_world Oyuncu dünyada bir oyuncu gerektirir
  • world text Dünya adı
player.health_below Oyuncunun X'ten az kalbi var bir oyuncu gerektirir

Can puanı cinsinden: 20 puan 10 kalbe eşittir.

  • value number [0..1024] Can puanı
text.contains Bir metin içerir
  • text text İncelenen metin
  • search text İçinde aranan şey
  • ignoreCase boolean isteğe bağlı, varsayılan: true Büyük/küçük harfi yok say
text.equals Bir metin eşittir
  • text text İncelenen metin
  • value text Beklenen değer
  • ignoreCase boolean isteğe bağlı, varsayılan: true Büyük/küçük harfi yok say
number.compare İki sayıyı karşılaştır

Her iki taraf da birer şablondur: {y}, kod yazmadan 62 ile karşılaştırılır.

  • left text Sol taraf
  • operator < | <= | == | != | >= | > Karşılaştırma
  • right text Sağ taraf
chance Rastgele, zamanın %X'inde
  • percent number [0..100] Yüzde

Eylemler

Gerçekleşen şey. Kural başına bir ile 50 arası, sırayla çalıştırılır.

player.send_message Oyuncuya mesaj gönder bir oyuncu gerektirir
  • message text Mesaj
player.send_actionbar Eylem çubuğunun üzerinde mesaj göster bir oyuncu gerektirir
  • message text Mesaj
player.send_title Büyük bir başlık göster bir oyuncu gerektirir
  • title text Başlık
  • subtitle text isteğe bağlı Alt başlık
  • fadeIn number [0..60] isteğe bağlı, varsayılan: 0.5 Saniye cinsinden belirme süresi
  • stay number [0..600] isteğe bağlı, varsayılan: 3 Saniye cinsinden süre
  • fadeOut number [0..60] isteğe bağlı, varsayılan: 0.5 Saniye cinsinden kaybolma süresi
player.play_sound Oyuncu için bir ses çal bir oyuncu gerektirir
  • sound identifier Ses, Minecraft anahtarı olarak (entity.player.levelup)
  • volume number [0..10] isteğe bağlı, varsayılan: 1 Ses düzeyi
  • pitch number [0.5..2] isteğe bağlı, varsayılan: 1 Perde
player.give_item Oyuncuya eşya ver bir oyuncu gerektirir

Envantere sığmayanlar ayaklarının dibine düşer.

  • material identifier Eşya (DIAMOND_SWORD)
  • amount integer [1..2304] isteğe bağlı, varsayılan: 1 Miktar
player.give_effect Oyuncuya bir efekt uygula bir oyuncu gerektirir
  • effect identifier Efekt, Minecraft anahtarı olarak (night_vision)
  • seconds integer [1..86400] isteğe bağlı, varsayılan: 10 Saniye cinsinden süre
  • amplifier integer [0..255] isteğe bağlı, varsayılan: 0 Seviye, 0'dan başlayarak
player.heal Oyuncuyu iyileştir bir oyuncu gerektirir

Can tamamen dolar, açlık giderilir.

player.teleport Oyuncuyu ışınla bir oyuncu gerektirir
  • x number [-30000000..30000000] X koordinatı
  • y number [-512..1024] Yükseklik
  • z number [-30000000..30000000] Z koordinatı
  • world text isteğe bağlı Dünya, oyuncununki için boş
player.kick Oyuncuyu at bir oyuncu gerektirir
  • reason text Gösterilen sebep
broadcast Tüm sunucuya duyur
  • message text Mesaj
server.run_command Konsol olarak bir komut çalıştır

Dilbilgisinin çıkış kapısı: konsolun yapabildiği her şey. Bu, konsolun bu sunucu üzerindeki tüm gücüdür, o yüzden ne yaptığını bilerek yaz.

  • command text Komut, eğik çizgi olmadan
cancel_event Az önce olanı iptal et iptal edilebilir bir tetikleyici gerektirir

Yalnızca iptal edilebilir tetikleyicilerde bulunur: mesaj iletilmez, blok kırılmaz.

log Sunucu konsoluna yaz
  • message text Mesaj
  • level info | warn isteğe bağlı, varsayılan: info Seviye
delay Bekle

Kuralın geri kalan eylemlerini duraklatır. Bekleyen bir kural artık hiçbir şeyi iptal edemez: "İptal et" ondan önce gelmelidir.

  • seconds number [0.05..3600] Saniye

Yayınlanan dosyalar

JSON Schema, her dağıtımda katalogdan üretilir ve makine tarafından okunabilir referans budur: onu izleyen bir metin editörü tanımlayıcıları tamamlar ve bilinmeyen parametreleri reddeder.

  • plugin-1.schema.json : şema, JSON Schema draft 2020-12 biçiminde.
  • catalogue-1.json : katalogun kendisi, geri kalan her şeyin türediği kaynak (doğrulayıcı, şema, editörün blokları ve Java motoru).

Katalog, kaynak dil olan Fransızca etiketleri taşır. Tanımlayıcılar ise çevrilmez: motorun çalıştırdığı onlardır.

Gramer değiştiğinde ne olur

Bir tetikleyici, koşul veya eylem eklemek hiçbir şeyi bozmaz: daha önce yazılmış bir spec çalışmaya devam eder. Bir kırıcı değişiklik ise specVersion'ı artırır ve motor, anlamadığı şeyi yanlış çalıştırmak yerine reddeder, bunu sunucu konsolunda belirtir.

Yukarıdaki URL'ler bu numarayı taşır: plugin-1.schema.json, başka bir gramer var olduğu gün bile her zaman bu grameri işaret edecektir.