Vai al contenuto
ShadowMC

Configurazione

ShadowCommand

Se sai scrivere un file YAML, sai programmare il tuo server.

Gratuito con Premium v1.0.4

Dove sono i file

plugins/ShadowCommand/

Il plugin li crea al primo avvio e li aggiorna da solo alle nuove versioni, senza toccare le tue modifiche.

Applicare le modifiche

/scmd reload [file]

Rilegge i file senza riavviare il server.

Cosa c’è dentro

11 file · 172 impostazioni

Da dove partire: config.yml

Impostazioni

I file che decidono come si comporta il plugin. Si parte da qui.

config.yml

Impostazioni generali
77 impostazioni
plugins/ShadowCommand/config.yml
Note del file

Ogni valore qui dentro ha già il numero giusto per un server normale: puoi mettere il jar e non aprire mai questo file. Quando devi cambiare qualcosa, la riga sopra ogni chiave dice cosa fa e la riga sotto dice cosa succede se sbagli.

Le durate si scrivono in testo semplice: 500ms, 20t (tick), 30s, 5m, 2h30m, 7d. Un numero da solo vale secondi.

I colori si scrivono con &: &a &c &l &r, e &#FF8800 per un colore esatto. I gradienti sono l'unica eccezione: <gradient:#a:#b>text</gradient>.

Chiavi, sezioni e commenti sono in inglese ovunque in ShadowCommand. Tutto ciò che legge un giocatore è un messaggio, e i messaggi stanno in lang/: scrivili nella lingua che parla il tuo server.

config-version3

Licenza

ShadowCommand è un unico jar con due edizioni dentro. Senza chiave gira l'edizione FREE: tutto il motore, con un tetto a quanti comandi, GUI, trigger e schedule puoi avere. Con una chiave firmata gira Premium, senza tetti.

Continua a leggere

Il plugin non si spegne mai da solo per un problema di licenza. Il caso peggiore è tornare alla free, dicendo in console perché.

Di norma qui non tocchi niente: una chiave si attiva in gioco con

/scmd license claim <purchase-code>    (quello che hai ricevuto all'acquisto)
/scmd license activate <key>           (se hai già una chiave)

e viene scritta in license.yml, che sta fuori da questo file apposta: una config si manda al supporto, una licenza no.

license4 chiavi

LA CHIAVE VIVE IN license.yml (stessa cartella di questo file), oppure nel file centrale plugins/ShadowControl/licenses.yml per tutta la suite. La 'key' qui sotto è solo un ripiego per i sistemi di deploy che generano config.yml: lasciala vuota.

La chiave NON sta qui: sta in license.yml, in questa cartella, creato al primo avvio (oppure in plugins/ShadowControl/licenses.yml per tutta la suite). Solo se preferisci tenerla qui invece che in license.yml. Funzionano anche la variabile d'ambiente SHADOWCOMMAND_LICENSE e la system property -Dshadowcommand.license=...

grace-days7

Giorni di tolleranza prima di tornare alla free quando un abbonamento scade o quando l'indirizzo del server non corrisponde alla licenza. Un rinnovo è quasi sempre già andato a buon fine, e un indirizzo che non torna è molto più spesso un NAT che un ladro.

server-ip""

L'indirizzo con cui è conosciuto questo server, se lo sai. Dietro un proxy la macchina non vede mai il proprio dominio, e questa riga è l'unico modo per dirglielo senza chiamare nessuno.

resolve-public-iptrue

Una chiamata, all'avvio, per scoprire l'indirizzo pubblico di questo server: dietro NAT è l'unico modo per riconoscerlo. La risposta arriva dal servizio di attivazione qui sotto (il suo indirizzo /ip), a nessun altro si chiede niente. Se la spegni e la licenza è legata a un dominio, il periodo di tolleranza vale comunque. Solo con una licenza installata: un server senza chiave non chiede niente a nessuno. false = non chiedere mai.

activation-url'https://shadow-licences.riccardobotins.workers.dev'

Servizio di attivazione. Questo è l'indirizzo BASE: il plugin aggiunge /claim, /check e /ip da solo.

Vuoto     = verifica completamente offline, e la chiave si incolla a mano.
Impostato = /scmd license claim <code> fa tutto da solo, e

ogni tre ore il server controlla che la licenza non sia stata revocata.

messages3 chiavi
default-locale"en_US"

Lingua usata quando quella del giocatore non è disponibile, e dalla console. Include en_US e it_IT. Imposta "it_IT" per un server italiano.

follow-client-localetrue

Ogni giocatore vede la lingua del proprio client, se il file esiste.

auto-updatetrue

Con un aggiornamento, i tuoi file (questo, lang/ e gli altri file creati dal plugin) vengono portati alla nuova versione automaticamente: arrivano le nuove impostazioni e i messaggi corretti, e tutto ciò che avevi cambiato o aggiunto viene mantenuto. I vecchi file vengono conservati in backup/<date>/; se qualcosa richiede la tua attenzione troverai PORTING-<version>.txt nella cartella del plugin, con cosa correggere. Metti false per non far toccare niente: le nuove impostazioni e i messaggi vengono allora letti dal plugin stesso.

storage6 chiavi
table-prefix"sc_"

Prefisso delle tabelle. Cambialo solo se condividi un database con qualcos'altro.

fallback-to-localtrue

Se MySQL non risponde, parti sul file locale invece di bloccare l'avvio.

flush-interval"30s"

Ogni quanto le variabili e i cooldown modificati vengono scritti su disco.

storage.mysql7 chiavi
enabledfalse

Metti true e compila i campi qui sotto: il plugin crea le tabelle da solo.

host"127.0.0.1"
port3306
database"shadowcommand"
username"root"
password""
parameters"useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=UTC&characterEncoding=utf8"
storage.pool5 chiavi
maximum-pool-size10
minimum-idle2
connection-timeout-ms10000
idle-timeout-ms600000
max-lifetime-ms1800000
storage.h21 chiave
auto-serverfalse

Permette a un altro programma di aprire il file locale mentre il server è acceso. Ti serve solo per guardarci dentro con uno strumento esterno.

engine5 chiavi
case-insensitive-comparetrue

"YES" e "yes" sono uguali nei confronti. Metti false per distinguerli.

strict-by-defaultfalse

true = il primo errore ferma sempre lo script. Di base un'azione che fallisce viene segnalata e lo script va avanti.

default-cooldown0

Cooldown applicato ai comandi che non ne dichiarano uno. 0 = nessuno.

deny-sound"block.note_block.bass"

Suono riprodotto quando un requisito nega l'accesso. Vuoto per il silenzio.

engine.limits6 chiavi
max-steps10000

Massimo di istruzioni per esecuzione: ferma un loop che non finisce mai.

max-depth16

Profondità massima delle chiamate: ferma due funzioni che si chiamano a vicenda.

max-sessions-per-player8

Script contemporanei per giocatore.

max-wait"10m"

Durata massima di un wait:. Un wait più lungo viene ridotto a questo valore.

max-command-chain8

Un comando che esegue un comando che esegue un comando...

action-warn-millis25

Oltre questa soglia una singola azione viene registrata come lenta, e oltre quattro volte tanto viene registrato anche un tratto di script che ha tenuto occupato il thread senza mai mollarlo. L'attesa non conta: uno script che dice "wait: 1s" resta fermo per un secondo senza tenere occupato niente, ed è proprio per questo che wait esiste.

commands5 chiavi
auto-permissiontrue

Genera shadowcommand.command.<name> per i comandi senza un permesso scritto.

auto-permission-defaulttrue

Chi può usare un comando che non dichiara un permesso: true | op | false

register-permissionstrue

Registra i permessi generati sul server, così LuckPerms li completa.

unknown-argument-shows-usagetrue

Un argomento sbagliato mostra la riga d'uso completa.

tab-complete-hiddenfalse

Completa col Tab anche i comandi nascosti.

security7 chiavi
security.op-action3 chiavi

L'azione op: esegue un comando dalla console, con i segnaposto del giocatore già sostituiti: scrivi il giocatore nel comando quando serve (op: gamemode creative {player}). Non rende mai nessuno operatore. Fino alla 1.0.3 lo faceva, per una riga: i file che usano op: vengono elencati in console all'avvio. Si ferma anche quando console-action.allowed qui sotto è false.

enabledtrue
allowed-commands[ ]

Vuoto = qualsiasi comando. Altrimenti solo quelli elencati.

logtrue

Ogni uso viene registrato in console con chi, cosa e da quale comando.

security.bypass-action1 chiave

L'azione bypass: esegue un comando concedendo un permesso per un istante.

enabledtrue
security.console-action1 chiave

L'azione console: (e op:, che esegue anche lei dalla console).

allowedtrue
security
forbidden-commands[stop, op, deop, reload]

Comandi che nessuno script può eseguire, in nessun modo. Questo è il freno d'emergenza: un file scritto male non deve poter spegnere il server.

security.block-actions2 chiavi

Le azioni che cambiano i blocchi: fill, cylinder, move, paste...

Di base NON chiedono un permesso, e non è una svista: l'uso normale è un tuo comando che apre un cancello a qualsiasi giocatore, e pretendere che quel giocatore abbia un permesso da builder romperebbe ogni comando di quel tipo. Attivalo quando il tuo staff può scrivere comandi ma non deve poter riscrivere la mappa.

require-permissionfalse
permission"shadowcommand.blocks"
security
max-broadcast-per-second10

Protezione contro un annuncio ripetuto per sbaglio a ogni tick.

escape-player-inputtrue

Tutto ciò che scrive un giocatore - il nome dell'item in mano, il testo su un cartello, gli argomenti di un comando - viene disinnescato prima di finire in un messaggio: un "<click:run_command:...>" scritto in un nickname resta scritto, non diventa un pulsante. Lascialo attivo.

Modifica dei blocchi

Un pavimento non è un blocco, sono quarantamila. Le azioni fill, cylinder, sphere, move e paste non li piazzano tutti in una volta: ne fanno qualche migliaio per tick finché non hanno finito, così una piazza sorge in due secondi senza che il server perda un colpo.

Continua a leggere

Tutto ciò che sta in un chunk e dentro il budget di un tick avviene SUBITO: un cancello si apre nello stesso istante, non al tick dopo.

blocks5 chiavi
max-blocks500000

Il paracadute contro uno zero di troppo. Un fill scritto male riscrive mezzo mondo, e questa riga è la differenza tra un errore e un disastro.

per-tick4000

Quanti blocchi per tick al massimo. Più alto = più veloce e più pesante.

undo-history5

Quante operazioni si possono annullare con l'azione undo, per giocatore. 0 disattiva undo e non tiene niente in memoria.

undo-max-blocks50000

Un'operazione più grande di così non viene registrata per l'undo: tenere mezzo milione di blocchi in memoria per un "forse" non vale la pena.

physicsfalse

Se il mondo deve reagire mentre si riempie (sabbia che cade, torce che saltano via). Spento è molto più veloce ed è quasi sempre ciò che vuoi: per un singolo cancello o una porta usa physics:true nell'azione stessa.

triggers3 chiavi
enabledtrue

Spegne tutti i trigger in una volta, senza cancellare i file.

move-check-interval4

Tick tra due controlli di player-move-block.

region-check-interval10

Tick tra due controlli delle regioni, per region-enter e region-exit.

menus4 chiavi
default-update-interval0

Aggiornamento live di base, in tick. 0 = solo quando serve.

click-delay-millis100

Protezione dal doppio clic, in millisecondi.

max-depth8

Quanti menu si possono annidare prima che si fermi.

return-items-on-quittrue

Restituisce gli item lasciati dentro una GUI che li accetta.

variables3 chiavi
cache-offline-minutes10

Quanto restano in memoria le variabili di chi è appena uscito.

purge-after-days0

Cancella le variabili di chi non entra da questo numero di giorni. 0 = mai.

expire-check-interval"1h"

Ogni quanto vengono ripuliti quelli scaduti.

logging4 chiavi
logging.audit2 chiavi
enabledfalse

Registra ogni esecuzione nel database: chi, cosa, con quale esito.

keep-days30

Per quanti giorni tenere le righe.

logging
debugfalse

Log molto dettagliato, utile solo mentre dai la caccia a un problema.

log-slow-actionstrue

Segnala le azioni più lente della soglia in engine.limits.

log-sqlfalse

Scrive ogni query nel log. Solo per capire un problema del database.

compatibility3 chiavi
dollar-placeholderstrue

Accetta $player, $arg1, $world come MyCommand.

section-color-codestrue

Accetta il carattere di sezione oltre a &.

mycommand-typestrue

Accetta type: RUN_COMMAND, runcmd:, permission-required e simili.

integrations4 chiavi
suitetrue

Si aggancia a ShadowEssentials e agli altri plugin della suite.

vaulttrue

Economia e permessi tramite Vault.

placeholderapitrue

Lettura e fornitura dei placeholder %...%.

regionstrue

ShadowRegions o WorldGuard, per i trigger e il requisito region:.

bStats - statistiche d'uso anonime (https://bstats.org)

Cosa viene inviato, ogni 30 minuti: che questo server usa ShadowCommand, le versioni del plugin, di Minecraft/Paper e di Java, il sistema operativo, il numero di core della CPU, quanti giocatori sono online (un numero, nient'altro), un serverUuid casuale che non identifica niente, e l'edizione in uso (free, premium o creator). Nessun dato dei giocatori lascia il server: niente nomi, niente UUID, niente indirizzi, e niente dei tuoi comandi, menu o script.

metrics1 chiave
enabledtrue

false lo spegne solo per questo plugin. enabled: false in plugins/bStats/config.yml lo spegne in un colpo solo per tutti i plugin di questo server.

overrides.yml

I comandi sostituiti
4 impostazioni
plugins/ShadowCommand/overrides.yml
Note del file

Qui decidi cosa fare con i comandi degli altri plugin: bloccarli, sostituirli con uno script tuo, o dargli un nome più corto.

Il controllo avviene su ciò che il giocatore scrive, non sull'albero dei comandi, quindi funziona con i plugin che si registrano dopo di noi e intercetta anche gli alias (/pl oltre a /plugins).

Il permesso shadowcommand.bypass.block salta ogni blocco.

config-version2

Comandi bloccati

block

Di serie non è bloccato niente: questi sono esempi, e funzionano appena togli i segni di commento.

- command: "plugins"
  aliases-too: true              # blocca anche /pl e /?
  bypass-permission: "server.seeplugins"
  message: "&7This command is &cnot available&7."
- command: "me"
  message: "&7This command is &cturned off&7 on this server."
- command: "minecraft:tell"
  aliases-too: false

Comandi sostituiti da un nostro script

intercept
- command: "spawn"
  cancel-original: true          # false = esegue anche l'originale
  run:
    - "message: &7Taking you to spawn..."
    - "wait: 2s"
    - "teleport: spawn"
    - "sound: entity.enderman.teleport"

Alias: scrivi una cosa, ne esegui un'altra

alias

Il nome a sinistra diventa ciò che sta a destra, argomenti compresi. gm0: "gamemode survival" gm1: "gamemode creative" w: "msg"

panel.yml

Il pannello
8 impostazioni
plugins/ShadowCommand/panel.yml
Note del file

Come appare il pannello che apre /scmd.

Tutto quello che c'è qui ha già un fallback nel codice: cancellare una chiave non rompe niente, torna semplicemente al valore integrato.

Gli slot si contano da 0. Il pannello è alto cinque righe (0-44).

Le chiavi sono in inglese. LE PAROLE: un titolo o un nome scritto "lang:<key>" arriva dai file di lingua in lang/, sotto admin.gui.panel, così ogni admin lo legge nella sua lingua. Scrivi invece un testo - per esempio name: "&e&lMy commands" - e quel testo viene mostrato così com'è, a tutti: quello che scrivi qui vince sul file di lingua. Lo stesso vale per una lore che aggiungi tu.

config-version2
panel15 chiavi
title"lang:admin.gui.panel.title"
Ancora 12 voci con la stessa forma di title: rows, filler, menus, triggers, schedules, variables, stats, errors, vocabulary, close, import, info

le otto porte

panel.commands3 chiavi
slot10
materialCOMMAND_BLOCK
name"lang:admin.gui.panel.commands"
lore: [ ... ]   # scrivine una e sostituisce la lore automatica

la riga in basso

panel.reload3 chiavi

Chiudi sta al centro dell'ultima riga, dove sta in ogni altra finestra del plugin - il menu di esempio e la lista delle variabili lo mettono entrambi lì. Prima era nell'angolo, e il libro della versione al centro: due finestre una accanto all'altra chiedevano due clic diversi.

slot38
materialLIME_CONCRETE
name"lang:admin.gui.panel.reload"

schedules.yml

I comandi a orario
15 impostazioni
plugins/ShadowCommand/schedules.yml
Note del file

Le cose che succedono da sole. Tre modi per dire quando:

every: "10m"        ogni tanto
at: "04:00"         a un'ora del giorno, ogni giorno
cron: "0 * * * *"   minuto ora giorno mese giorno-della-settimana

Chiavi utili:

enabled          ne spegne una senza eliminarla
on-start         la esegue anche una volta all'avvio del server
for-each-player  si ripete per ogni giocatore online, con {player} compilato
async            gira fuori dal thread principale (solo azioni sicure)
conditions       gli stessi requisiti che usano i comandi

Di serie c'è un annuncio, spento. Accendilo per vedere come si comporta.

Quello che legge un giocatore è in inglese: sta a te riscriverlo. Una versione italiana di questo file è in esempi/it_IT/schedules.yml. Non viene caricata: copiala al posto di questo per usarla.

config-version2
schedules4 chiavi
schedules.announcement3 chiavi

Un annuncio ogni dieci minuti. Spento: accendilo quando lo vuoi.

enabledfalse
every"10m"
run["broadcast: &8[&fInfo&8] &7Type &f/rules&7 to…]
schedules.wage5 chiavi

Una paga oraria per chi ha il permesso. Spenta di base: tocca l'economia, e nessuno dovrebbe trovarsi soldi in tasca senza averlo deciso.

enabledfalse
cron"0 * * * *"
for-each-playertrue
conditions["permission: server.wage"]
run
["money: give 100", "actionbar: &7+&a100 coins&7 &8(hourly wage)"]+1
schedules.cleanup3 chiavi

Pulizia degli item a terra, con due minuti di preavviso.

enabledfalse
every"30m"
run
["broadcast: &8[&fCleanup&8] &7Items on the ground will disappear in &f2 minutes&7.", "wait: 1m", "broadcast: &8[&fCleanup&8] &f1 minute&7 left.", "wait: 50s", "broadcast: &8[&fCleanup&8] &7In &c10 seconds&7.", "wait: 1 …+7
schedules.nightly-backup3 chiavi

Un backup notturno. Il comando dipende dal tuo host: cambialo.

enabledfalse
at"04:00"
run["console: save-all", "log: nightly save done"]

commands/examples.yml

Comandi personalizzati
7 impostazioni
plugins/ShadowCommand/commands/examples.yml
Note del file

Un catalogo: un esempio di ogni tipo di comando che puoi costruire.

TRE SONO ATTIVI - /rules, /discord e /examplemenu funzionano appena il server parte. Tutto il resto è commentato, così un'installazione nuova resta pulita e nella lista dei comandi non compare niente che non hai chiesto.

PER ATTIVARNE UNO, togli i due caratteri "# " dall'inizio di ogni riga del blocco e lancia /scmd reload. L'indentazione sotto è già giusta.

Crea tutti i file che vuoi in questa cartella, sottocartelle comprese. Il nome del file non significa niente per il plugin: serve solo a farti ritrovare le cose.

Tutto quello che scrivi - nomi dei comandi, chiavi, opzioni, valori - è in inglese. Tutto quello che legge un giocatore è un messaggio, e i messaggi li scrivi tu nella lingua che vuoi: quelli qui sotto arrivano in inglese. Una versione italiana di questo file è in esempi/it_IT/commands/examples.yml. Non viene caricata: copiala al posto di questo per usarla.

STILE DEI MESSAGGI, lo stesso che usa lang/:

&7 il corpo della frase          &f le parole che contano
&c cosa è sbagliato o manca      &a cosa è appena andato bene
&8 la parte sommessa             niente &l: un messaggio si legge, non si urla

Placeholder con {}: {player} {arg1} {var:points} {math:1+2} La lista completa è in /scmd placeholders e in docs/09-VARIABILI.md.

config-version2

01 Solo testo attivo

Il comando più corto che esista: una lista di righe, niente script. Va bene per regole, info, liste dello staff, tutto ciò che deve solo essere stampato.

rules2 chiavi
description"The server rules"
text
["&8&m ", "&fServer rules", "&8 1 &7Respect the others.", "&8 2 &7No cheats or third-party programs.", "&8 3 &7No advertising other servers.", "&8 4 &7Have fun.", "&8&m …+6

03 Apre una GUI attivo

Una riga, e il comando apre menus/example.yml. La stessa finestra si può aprire da uno script con menu: example.

examplemenu2 chiavi
description"Opens the example menu"
menu"example"

04 Alias, riga D'uso e visibilità

Tutto ciò che un comando può dire di sé. hidden: true lo tiene fuori dalla lista del Tab del client senza spegnerlo.

website:
  description: "The server website"
  aliases: [ "site", "web" ]
  usage: "/website"
  hidden: false
  run:
    - "message: &7Our website: &fwww.example.com"

05 Argomenti tipizzati

Il client li completa e il plugin li controlla prima che parta il tuo script. Tipi: player, offline-player, world, material, choice, int, decimal, word, text, boolean. {arg1} è il primo, {args:2-} tutto dal secondo in poi.

kit:
  description: "Claim a kit"
  permission: "server.kit.{arg1}"
  arguments:
    - name: "kind"
      type: choice
      values: [ "wood", "iron", "diamond" ]
      required: true
      error: "&7Pick one of &fwood&7, &firon&7 and &fdiamond&7."
    - name: "amount"
      type: int
      min: 1
      max: 5
      default: 1
      error: "&7The amount goes from &f1&7 to &f5&7."
  run:
    - "message: &7Here is the &f{arg1}&7 kit &8(x{arg2})"
    - "repeat: {arg2}"
    - "  if: {arg1} == diamond"
    - "    give: DIAMOND_SWORD 1 name:'&fKit sword' enchant:SHARPNESS:3 unbreakable"
    - "  elseif: {arg1} == iron"
    - "    give: IRON_SWORD 1"
    - "  else:"
    - "    give: WOODEN_SWORD 1"
    - "  end"
    - "end"
    - "sound: entity.player.levelup"

06 Sottocomandi

Un comando con dei figli, ognuno con il suo permesso, i suoi argomenti e il suo script. Annida quanto vuoi.

staff:
  description: "Staff tools"
  permission: "server.staff"
  permission-default: op
  run:
    - "message: &7Use &f/staff list&7 or &f/staff warn&7."
  subcommands:
list:
  description: "Who is online"
  run:
    - "message: &7Online: &f{server_online}&7/&f{server_max}"
    - "message: &7Names: &f{server_online_names}"
warn:
  description: "Send a player a warning"
  arguments:
    - { name: "target", type: player, required: true }
    - { name: "reason", type: text, required: true }
  run:
    - "tell: {arg1} &cWarning &8- &7{args:2-}"
    - "message: &7Warning sent to &f{arg1}&7."
    - "console: say &8[staff] &7{player} warned {arg1}"

07 Permessi

Un comando senza permission: riceve shadowcommand.command.<name> e ce l'hanno tutti. Scrivine uno, o una lista, e di' cosa succede quando il giocatore non ce l'ha.

vipkit:
  description: "The VIP kit"
  permissions: [ "server.vip", "server.bundle.kit" ]
  permissions-mode: any            # all (default) li richiede tutti, any ne richiede uno
  permission-message: "&7This kit is for &fVIPs&7. Have a look at &f/shop&7, {player}."
  run:
    - "give: DIAMOND 8"

08 Requisiti

Controllati prima che parta qualsiasi cosa: quando uno nega, non viene tolto niente e non succede niente. Sono 48, elencati da /scmd requirements. requirements-mode: all (default) | any | none

home:
  description: "Go back to your home"
  player-only: true
  requirements:
    - "world: !world_the_end"
    - type: condition
      value: "{var:home_x|none} != none"
      deny: "&7You have not set a home yet. Use &f/sethome&7."
    - type: condition
      value: "{health} > 4"
      deny: "&7You are &ctoo hurt&7 to teleport."
      sound: "block.note_block.bass"
  requirements-mode: all
  run:
    - "teleport: {var:home_x} {var:home_y} {var:home_z} {var:home_world}"
    - "message: &7Welcome back &ahome&7."

09 Costo

Soldi, esperienza, livelli, fame, vita, item. Tutto o niente: se un pezzo non si può pagare, non viene tolto proprio niente.

repairhand:
  description: "Repair what you are holding"
  permission: "server.repair"
  requirements:
    - "item-in-hand: !AIR"
  cost:
    money: 250
    items:
      - "IRON_INGOT 4"
    message: "&7You paid &f250 coins&7 and &f4 ingots&7."
  run:
    - "console: repair {player}"
    - "message: &7Repaired. &aDone&7."
    - "sound: block.anvil_use"

10 Cooldown

Per giocatore, o uno per tutto il server. Sopravvive a un riavvio, quindi un kit da 24 ore dura davvero 24 ore.

daily:
  description: "The daily reward"
  cooldown: "24h"
  cooldown-persistent: true
  cooldown-bypass: "server.nocooldown"
  cooldown-message: "&7You already claimed the reward. Come back in &f{cooldown_left}&7."
  run:
    - "money: give 500"
    - "give: DIAMOND 1"
    - "message: &7Reward claimed. &aCome back tomorrow&7."

11 Warm-up

L'attesa prima che parta, con una boss bar, annullata se il giocatore si muove o subisce danni.

spawn:
  description: "Go back to spawn"
  player-only: true
  warmup: "5s"
  warmup-bossbar: true
  warmup-cancel-on-move: true
  warmup-cancel-on-damage: true
  run:
    - "teleport: 0 100 0 world"
    - "message: &7You are at &fspawn&7."
    - "sound: entity.enderman.teleport"

12 Conferma

La domanda arriva in chat con due pulsanti cliccabili e un codice monouso: nessuno può rispondere al posto tuo. Non far mai riscrivere un comando a un giocatore per confermarlo.

clearinv:
  description: "Empty your inventory"
  player-only: true
  confirm: true
  confirm-text: "&7You are about to empty &call&7 of your inventory."
  run:
    - "clear:"
    - "message: &7Inventory emptied."

13 Chi può eseguirlo

player-only tiene fuori la console, console-only tiene fuori i giocatori. Utile per tutto ciò che viene chiamato da uno scheduler o da un pannello.

announce:
  description: "Announcement from the console"
  console-only: true
  arguments:
    - { name: "text", type: text, required: true }
  run:
    - "broadcast: &8[&fInfo&8] &7{args}"
    - "sound-all: block.note_block.pling 0.5 1.5"

14 Variabili

var: questo giocatore, gvar: ognuno con la sua copia, svar: una per tutto il server. Stanno nel database, quindi sopravvivono a un riavvio e si possono condividere tra server tramite MySQL.

stats:
  description: "Your statistics"
  run:
    - "var: add opened 1"
    - "message: &8&m                                        "
    - "message: &7Statistics opened &f{var:opened}&7 times."
    - "message: &7Health: &f{health}&7/&f{maxhealth}   &7Level: &f{level}"
    - "message: &7World: &f{world}   &7Ping: &f{ping}ms"
    - "message: &7Play time: &f{playtime}"
    - "message: &8&m                                        "

15 Condizioni

if / elseif / else / end, con confronti su qualsiasi cosa: numeri, testo, placeholder, espressioni libere.

health:
  description: "How are you doing"
  player-only: true
  run:
    - "if: {health} >= 18"
    - "  message: &7You are &avery well&7. &8({health}/{maxhealth})"
    - "elseif: {health} >= 8"
    - "  message: &7You are a bit &fbattered&7. &8({health}/{maxhealth})"
    - "else:"
    - "  message: &7You are in &cbad shape&7! &8({health}/{maxhealth})"
    - "  effect: REGENERATION 10 1"
    - "end"

16 Cicli e attese

repeat, while, for, break e wait: - che sospende lo script senza tenere fermo il server nemmeno per un tick.

countdown:
  description: "A countdown"
  permission: "server.staff"
  run:
    - "for: n in 5,4,3,2,1"
    - "  broadcast: &7Starting in &f{n}&7..."
    - "  sound-all: block.note_block.hat"
    - "  wait: 1s"
    - "end"
    - "broadcast: &aGo!"
    - "sound-all: block.note_block.pling 1 2"

17 Probabilità e casualità

chance: N apre un blocco che viene eseguito N volte su cento, e {rand:...} sceglie un numero o una voce.

crate:
  description: "Open a prize crate"
  cooldown: "1h"
  cost:
    items:
      - "TRIPWIRE_HOOK 1"
  run:
    - "repeat: 5"
    - "  actionbar: &7Drawing &f{rand:iron,gold,diamond,emerald}"
    - "  sound: block.note_block.hat"
    - "  wait: {math:{loop}*4}t"
    - "end"
    - "chance: 2"
    - "  give: NETHER_STAR 1"
    - "  broadcast: &f{player} &7drew a &fNether star&7!"
    - "  stop"
    - "end"
    - "chance: 20"
    - "  give: DIAMOND 8"
    - "  message: &7You won &f8 diamonds&7."
    - "  stop"
    - "end"
    - "money: give {rand:50-250}"
    - "message: &7Consolation prize: &f{result} coins&7."

18 Funzioni

Un blocco di script che altri comandi possono chiamare, con argomenti e un valore di ritorno. Possono stare qui sotto functions:, o in un file tutto loro: vedi functions/examples.yml.

vote:
  description: "Vote for the server"
  run:
    - "call: separator"
    - "message: &7Vote here: &fwww.example.com/vote"
    - "call: separator"
functions:
  separator:
    run:
      - "message: &8&m                                        "

19 Costruire da un comando

fill, hollow, walls, outline, replace, cylinder, sphere, move, copy, paste, undo e blockdata. ~ è dove si trova il giocatore. Un cancello è una riga di blockdata, e si apre nello stesso istante.

gate:
  description: "Opens and closes the gate"
  permission: "server.gate"
  cooldown: "2s"
  run:
    - "blockdata: 102 71 102 toggle=open"
    - "blockdata: 103 71 102 toggle=open"
    - "sound: block.fence_gate.open"
    - "message: &7The gate moves."
floor:
  description: "A floor under your feet"
  permission: "server.builder"
  player-only: true
  run:
    - "fill: ~-3 ~-1 ~-3 ~3 ~-1 ~3 SMOOTH_STONE"
    - "message: &7Done. If you do not like it: &f/revert"
revert:
  description: "Undo the last block changes"
  permission: "server.builder"
  run:
    - "undo: 1"
    - "message: &7Put back &aas it was&7."

20 Eseguire qualcosa che il giocatore non potrebbe

console: esegue dalla console. Anche op: esegue dalla console, con i segnaposto del giocatore già sostituiti (op: gamemode creative {player}), e ogni uso di op: viene registrato con chi e cosa: non rende mai nessuno operatore. bypass: dà un permesso solo per una riga, runas: esegue la riga come qualcun altro.

giverank:
  description: "Give a player a rank"
  permission: "server.staff.rank"
  arguments:
    - { name: "target", type: player, required: true }
    - { name: "rank", type: choice, values: [ "vip", "vip+", "mvp" ], required: true }
  confirm: true
  confirm-text: "&7You are about to give &f{arg2}&7 to &f{arg1}&7."
  run:
    - "bypass: luckperms.user.parent.add | lp user {arg1} parent add {arg2}"
    - "tell: {arg1} &7You received the rank &a{arg2}&7."
    - "broadcast: &f{arg1} &7is now &f{arg2}&7."
    - "log: [ranks] {player} gave {arg2} to {arg1}"

21 Finali alternativi

Cosa fare quando qualcosa dice di no. Senza questi il giocatore riceve solo il messaggio standard di lang/.

shop:
  description: "Opens the shop"
  menu: "shop"
  cooldown: "3s"
  requirements:
    - "world: !world_the_end"
  on-deny:
    - "sound: block.note_block.bass"
  on-cooldown:
    - "message: &7Another &f{cooldown_left}&7 before you can open it again."
  on-error:
    - "message: &7Something went wrong, try again."

22 Placeholder di altri plugin

%...% è PlaceholderAPI: qui puoi leggere tutto ciò che pubblica qualsiasi altro plugin. Senza PlaceholderAPI installato restano scritti così come sono.

profile:
  description: "Your profile"
  run:
    - "message: &7Rank: &f%vault_group%"
    - "message: &7Balance: &f{money_formatted}"
    - "message: &7Position: &f{x}, {y}, {z} &8({world})"

functions/examples.yml

Funzioni
6 impostazioni
plugins/ShadowCommand/functions/examples.yml
Note del file

Una funzione è un blocco di script che altri script possono chiamare:

- "call: reward 3 'first join'"
- "message: &7The function returned {result}."

Gli argomenti diventano variabili locali, così non toccano mai le variabili del giocatore. La ricorsione è ammessa fino al limite in config.yml (engine.limits.max-depth).

Le funzioni possono anche stare dentro un file di comandi, sotto una chiave "functions:": qui sono insieme solo perché si legge meglio.

Quello che legge un giocatore è in inglese: sta a te riscriverlo. Una versione italiana di questo file è in esempi/it_IT/functions/examples.yml. Non viene caricata: copiala al posto di questo per usarla.

config-version2
functions3 chiavi
functions.reward2 chiavi

Dà dei diamanti, lo dice, e restituisce quanti ne ha dati.

args[amount, reason]
run
["give: DIAMOND {amount}", "message: &7+&f{amount}&7 diamonds &8({reason})", "sound: entity.experience_orb.pickup", "return: {amount}"]+3
functions.separator1 chiave

Una riga separatrice, perché scriverla ogni volta stanca.

run["message: &8&m…]
functions.announce2 chiavi

Un annuncio nel formato del server, scritto una volta sola: cambialo qui e cambia ovunque.

args[text]
run
["broadcast: &8[&fInfo&8] &7{text}", "sound-all: block.note_block.pling 0.5 1.5"]+1

Lingue

I testi che il plugin mostra ai giocatori, un file per lingua.

lang/

Testi e messaggi
2 file
plugins/ShadowCommand/lang/
Note del file

Questo file contiene ciò che leggono i giocatori, ed è l'ultimo ripiego: una chiave che manca in tutte le altre lingue finisce qui. Le chiavi sono in inglese come in tutto il resto del plugin; solo i valori sono testo per un giocatore, quindi si traducono solo i valori.

STILE DELLA CASA - mantienilo quando modifichi queste righe:

&7 è il corpo di ogni messaggio. Nient'altro.
&f segna le parole che contano: nomi, numeri, file, comandi.
&c segna ciò che manca, è bloccato o è sbagliato.
&a segna ciò che è appena andato bene.
&8 è per la parte sottovoce: id, suggerimenti, separatori.
Niente &l in chat. Un messaggio si legge, non si urla.

I colori si scrivono con &: &a &c &r, e &#FF8800 per uno esatto. L'unica eccezione sono i gradienti, che nessun codice & può esprimere:

<gradient:#7E57C2:#4FC3F7>text</gradient>

I placeholder dei messaggi di sistema si scrivono <like_this>. Quelli che scrivi nei tuoi comandi e menu sono {like_this}.

Un messaggio può essere una stringa o una piccola mappa:

key:
  text: "&cText"
  channel: ACTION_BAR      # CHAT | ACTION_BAR | TITLE | SUBTITLE | NONE
  sound: block.note_block.bass
  volume: 0.7
  pitch: 0.8
  cooldown: "2s"           # anti spam, per giocatore

channel: NONE zittisce un messaggio senza cancellare la chiave.

Tutti i messaggi che il plugin mostra ai giocatori, un file per lingua. Le chiavi non sono elencate una per una: qui ci sono i file, quanti testi contengono e i segnaposto che usano.

FileLinguaTesti
lang/en_US.yml riferimento English 893
lang/it_IT.yml Italiano 893

Segnaposto più usati

Il plugin li sostituisce con il valore giusto: vanno lasciati scritti così.

  • <prefix>
  • <count>
  • <value>
  • <command>
  • <max>
  • <player>
  • <page>
  • <pages>
  • <name>
  • <error>
  • <status>
  • <where>
  • <id>
  • <file>

Gruppi di messaggi

  • prefix 1
  • common 20
  • command 31
  • cost 10
  • requirement 19
  • engine 4
  • problem 45
  • note 60
  • input 5
  • admin 364
  • license 51
  • blocks 2
  • catalog 281

Altro

Contenuti pronti, esempi, importazioni: i file che si copiano e si modificano come modello.

triggers/

Le reazioni automatiche
2 file
plugins/ShadowCommand/triggers/

2 file con la stessa forma. Qui sotto 2 esempi per intero, uno per ogni forma diversa; gli altri sono elencati per nome.

  • examples.yml
  • suite.yml

Esempio triggers/examples.yml

Note del file

Uno script che parte da solo quando succede qualcosa.

DUE SONO ATTIVI - il benvenuto al primo ingresso e la riga a ogni ingresso. Tutto il resto ha enabled: false ed è lì per essere letto e acceso: un esempio per ogni tipo di trigger.

I listener vengono registrati solo quando qualcuno li usa: spegni tutti i trigger di un tipo e quel listener non esiste nemmeno, quindi non costa niente. /scmd triggers mostra quali sono attivi e quante volte sono scattati.

STILE DEI MESSAGGI, lo stesso che usa lang/:

&7 il corpo della frase          &f le parole che contano
&c cosa è sbagliato o manca      &a cosa è appena andato bene
&8 la parte in secondo piano     niente &l in chat

Tutti i nomi degli eventi sono in docs/08-TRIGGER.md e in /scmd triggers.

Quello che legge un giocatore arriva in inglese: sta a te riscriverlo. Una versione italiana di questo file è in esempi/it_IT/triggers/examples.yml. Non viene caricata: copiala al posto di questo per usarla.

config-version2
triggers9 chiavi
Il primissimo ingresso di un giocatore. Scatta una sola volta per giocatore, in assoluto
triggers.welcome2 chiavi
eventplayer-first-join
run
["broadcast: &8[&a+&8] &f{player} &7joined for the first time.", "title: &fWelcome", "subtitle: &7Read the rules with &f/rules", "give: BREAD 16", "sound: entity.player.levelup"]+4
Ogni ingresso: una riga sull'action bar, così la chat resta pulita
triggers.greeting2 chiavi
eventplayer-join
run
["wait: 1s", "actionbar: &7Welcome back, &f{player}&7."]+1
triggers.diamonds6 chiavi

Un filtro sull'evento stesso: solo diamanti, solo un mondo, con un cooldown così una vena non intasa la chat.

eventblock-break
enabledfalse
block"DIAMOND_ORE,DEEPSLATE_DIAMOND_ORE"
world"world"
cooldown"3s"
run["broadcast: &f{player} &7found diamonds at &f…]
Un cartello che apre una GUI

La prima riga si colora automaticamente quando qualcuno la scrive, e può farlo solo chi ha il permesso.

triggers.menu-sign5 chiavi
eventsign-click
enabledfalse
line1"[Menu]"
create-permission"server.signs"
run["menu: example"]
Alla morte: una riga a chi è morto, con la causa e l'uccisore
triggers.death3 chiavi
eventplayer-death
enabledfalse
run
["message: &7You died&8: &c{death_cause}", "if: {killer} != ''", " message: &7You were killed by &c{killer}&7.", end]+3
Annullare un evento: qui i vasi di fiori non si possono rompere

cancel: true annulla sempre; l'azione "cancel" decide caso per caso.

triggers.protect-flowers6 chiavi
eventblock-break
enabledfalse
block"FLOWER_POT"
conditions["permission: !server.staff"]
canceltrue
run["message: &7Hands off &cthe flower pots&7."]
Entrare in una regione, e uscirne di nuovo. Serve ShadowRegions o

WorldGuard: senza uno dei due questo trigger non viene registrato.

triggers.arena-enter4 chiavi
eventregion-enter
enabledfalse
region"arena"
run
["title: &fArena", "subtitle: &7This is where we fight.", "sound: entity.ender_dragon.growl 0.4 1.4"]+2
Clic destro con un item scelto in mano

I nomi delle azioni sono quelli del server: RIGHT_CLICK_AIR quando davanti non c'è un blocco, RIGHT_CLICK_BLOCK quando c'è, quindi sono elencati entrambi.

triggers.compass-menu6 chiavi
eventitem-click
enabledfalse
item"COMPASS"
action"RIGHT_CLICK_AIR,RIGHT_CLICK_BLOCK"
cooldown"500ms"
run["menu: example"]
Chat: leggere cosa è stato scritto, e annullarlo quando serve

{message} è ciò che ha scritto il giocatore.

triggers.no-caps5 chiavi
eventplayer-chat
enabledfalse
conditions
["permission: !server.staff", "condition: {len:{message}} > 8", "condition: {upper:{message}} == {message}"]+2
canceltrue
run["message: &7Write in &clower case&7, please."]

Esempio triggers/suite.yml

Note del file

Reagire agli eventi di ALTRI plugin, senza dipendere da loro.

event: bukkit-event
class: "full.package.of.TheEventClass"

La classe viene cercata in ogni plugin attivo. Se il plugin che la definisce non è installato, il trigger resta spento e compare in /scmd errors con il nome che hai scritto: altrimenti un package sbagliato è la cosa più difficile da notare.

Ogni proprietà leggibile dell'evento diventa un placeholder:

getNewLevel()  ->  {new_level}
isPremium()    ->  {premium}
getPlayer()    ->  {player}

/scmd debug li elenca mentre succede.

Tutto quello che c'è qui è spento di fabbrica: accendi quello che ti serve.

Quello che legge un giocatore arriva in inglese: sta a te riscriverlo. Una versione italiana di questo file è in esempi/it_IT/triggers/suite.yml. Non viene caricata: copiala al posto di questo per usarla.

config-version2
triggers7 chiavi
ShadowBattlePass: qualcuno sale di un livello
triggers.pass-tier-up4 chiavi
enabledfalse
eventbukkit-event
class"net.shadowmc.battlepass.api.event.BattlePassTierUpEvent"
run
["broadcast: &8[&fPass&8] &f{player} &7reached tier &f{new_tier}&7.", "sound-all: entity.player.levelup 0.5 1.2"]+1
Ancora 5 voci con la stessa forma di pass-tier-up: pass-quest-done, pass-season-start, match-end, crate-open, variable-changed
triggers.match-join4 chiavi

ShadowGames: entrare in una partita. L'esperienza del pass viene data qui, così i due plugin si parlano senza sapere l'uno dell'altro.

enabledfalse
eventbukkit-event
class"net.shadowmc.games.api.event.GamePlayerJoinEvent"
run
["actionbar: &7You joined &f{game}&7.", "battlepass: event games-played 1"]+1

Tutta la documentazione