191 lines
6.7 KiB
Markdown
Executable File
191 lines
6.7 KiB
Markdown
Executable File
---
|
|
title: Chat e comandi
|
|
layout: default
|
|
root: ../..
|
|
idx: 4.2
|
|
description: Come registrare un comando e gestire i messaggi della chat
|
|
redirect_from: /it/chapters/chat.html
|
|
cmd_online:
|
|
level: warning
|
|
title: I giocatori offline possono eseguire comandi
|
|
message: |
|
|
Viene passato il nome del giocatore al posto del giocatore in sé perché le mod possono eseguire comandi in vece di un giocatore offline.
|
|
Per esempio, il ponte IRC permette ai giocatori di eseguire comandi senza dover entrare in gioco.
|
|
|
|
Assicurati quindi di non dar per scontato che un giocatore sia connesso.
|
|
Puoi controllare ciò tramite `core.get_player_by_name`, per vedere se ritorna qualcosa o meno.
|
|
|
|
cb_cmdsprivs:
|
|
level: warning
|
|
title: Privilegi e comandi
|
|
message: |
|
|
Il privilegio shout non è necessario per far sì che un giocatore attivi questo richiamo.
|
|
Questo perché i comandi sono implementati in Lua, e sono semplicemente dei messaggi in chat che iniziano con /.
|
|
|
|
---
|
|
|
|
## Introduzione <!-- omit in toc -->
|
|
|
|
Le mod possono interagire con la chat del giocatore, tra l'inviare messaggi, intercettarli e registrare dei comandi.
|
|
|
|
- [Inviare messaggi](#inviare-messaggi)
|
|
- [A tutti i giocatori](#a-tutti-i-giocatori)
|
|
- [A giocatori specifici](#a-giocatori-specifici)
|
|
- [Comandi](#comandi)
|
|
- [Accettare più argomenti](#accettare-più-argomenti)
|
|
- [Usare string.split](#usare-stringsplit)
|
|
- [Usare i pattern Lua](#usare-i-pattern-lua)
|
|
- [Intercettare i messaggi](#intercettare-i-messaggi)
|
|
|
|
## Inviare messaggi
|
|
|
|
### A tutti i giocatori
|
|
|
|
Per inviare un messaggio a tutti i giocatori connessi in gioco, si usa la funzione `chat_send_all`:
|
|
|
|
```lua
|
|
core.chat_send_all("Questo è un messaggio visualizzabile da tutti")
|
|
```
|
|
|
|
Segue un esempio di come apparirerebbe in gioco:
|
|
|
|
<Tizio> Guarda qui
|
|
Questo è un messaggio visualizzabile da tutti
|
|
<Caio> Eh, cosa?
|
|
|
|
Il messaggio appare su una nuova riga, per distinguerlo dai messaggi dei giocatori.
|
|
|
|
### A giocatori specifici
|
|
|
|
Per inviare un messaggio a un giocatore in particolare, si usa invece la funzione `chat_send_player`:
|
|
|
|
```lua
|
|
core.chat_send_player("Tizio", "Questo è un messaggio per Tizio")
|
|
```
|
|
|
|
Questo messaggio viene mostrato esattamente come il precedente, ma solo, in questo caso, a Tizio.
|
|
|
|
## Comandi
|
|
|
|
Per registrare un comando, per esempio `/foo`, si usa `register_chatcommand`:
|
|
|
|
```lua
|
|
core.register_chatcommand("foo", {
|
|
privs = {
|
|
interact = true,
|
|
},
|
|
func = function(name, param)
|
|
return true, "Hai detto " .. param .. "!"
|
|
end,
|
|
})
|
|
```
|
|
|
|
Nel codice qui in alto, `interact` è elencato come [privilegio](privileges.html) necessario; in altre parole, solo i giocatori che hanno quel privilegio possono usare il comando.
|
|
|
|
`param` è una stringa contenente tutto ciò che un giocatore scrive dopo il nome del comando.
|
|
Per esempio, in `/grantme uno,due,tre`, `param` equivarrà a `uno,due,tre`.
|
|
|
|
I comandi ritornano un massimo di due valori, dove il primo è un booleano che indica l'eventuale successo, mentre il secondo è un messaggio da inviare all'utente.
|
|
|
|
{% include notice.html notice=page.cmd_online %}
|
|
|
|
|
|
### Accettare più argomenti
|
|
|
|
Non è raro che i comandi richiedano più argomenti, come per esempio `/squadra entra <nome_squadra>`.
|
|
Ci sono due modi per implementare ciò: usare `string.split` o i pattern Lua.
|
|
|
|
|
|
#### Usare string.split
|
|
|
|
Una stringa può essere spezzettata in più parti tramite `string.split(" ")`:
|
|
|
|
```lua
|
|
local parti = param:split(" ")
|
|
local cmd = parti[1]
|
|
|
|
if cmd == "entra" then
|
|
local nome_squadra = parti[2]
|
|
squadra.entra(name, nome_squadra)
|
|
return true, "Sei dentro la squadra!"
|
|
elseif cmd == "gioc_max" then
|
|
local nome_squadra = parti[2]
|
|
local gioc_max = tonumber(parti[3])
|
|
if nome_squadra and gioc_max then
|
|
return true, "Giocatori massimi della squadra " .. nome_squadra .. " impostati a " .. gioc_max
|
|
else
|
|
return false, "Uso: /squadra gioc_max <nome_squadra> <numero>"
|
|
end
|
|
else
|
|
return false, "È necessario un comando"
|
|
end
|
|
```
|
|
|
|
|
|
#### Usare i pattern Lua
|
|
|
|
[I pattern Lua](https://www.lua.org/pil/20.2.html) sono un modo per estrapolare pezzi di testo seguendo delle regole.
|
|
Sono perfetti in caso di argomenti che contengono spazi, o comunque quando è richiesto un controllo più meticoloso dei parametri catturati.
|
|
|
|
```lua
|
|
local a, msg = string.match(param, "^([%a%d_-]+) (.+)$")
|
|
```
|
|
|
|
Il codice sovrastante implementa `/msg <a> <messaggio>`. Vediamo cos'è successo partendo da sinistra:
|
|
|
|
* `^` dice di iniziare a combaciare dall'inizio della stringa;
|
|
* `()` è un gruppo - qualsiasi cosa che combaci con ciò che è contenuto al suo interno verrà ritornato da string.match;
|
|
* `[]` significa che i caratteri al suo interno sono accettati;
|
|
* `%a` significa che accetta ogni lettera e `%d` ogni cifra.
|
|
* `[%a%d_-]` significa che accetta ogni lettera, cifra, `_` e `-`.
|
|
* `+` dice di combaciare ciò che lo precede una o più volte.
|
|
* `.` dice di combaciare qualsiasi tipo di carattere.
|
|
* `$` dice di combaciare la fine della stringa.
|
|
|
|
Detto semplicemente, il pattern cerca un nome (una parola fatta di lettere, numeri, trattini o trattini bassi), poi uno spazio e poi il messaggio (uno o più caratteri, qualsiasi essi siano).
|
|
Vengono poi ritornati nome e messaggio, perché sono inseriti nelle parentesi.
|
|
|
|
Questo è come molte mod implementano comandi complessi.
|
|
Una guida più completa ai pattern è probabilmente quella su [lua-users.org](http://lua-users.org/wiki/PatternsTutorial) o la [documentazione PIL](https://www.lua.org/pil/20.2.html).
|
|
|
|
<p class="book_hide">
|
|
C'è anche una libreria scritta dall'autore di questo libro che può essere usata
|
|
per creare comandi complessi senza l'utilizzo di pattern:
|
|
<a href="https://gitlab.com/rubenwardy/ChatCmdBuilder">Chat Command Builder</a>.
|
|
</p>
|
|
|
|
|
|
## Intercettare i messaggi
|
|
|
|
Per intercettare un messaggio, si usa `register_on_chat_message`:
|
|
|
|
```lua
|
|
core.register_on_chat_message(function(name, message)
|
|
print(name .. " ha detto " .. message)
|
|
return false
|
|
end)
|
|
```
|
|
|
|
Ritornando `false`, si permette al messaggio di essere inviato.
|
|
In verità `return false` può anche essere omesso in quanto `nil` verrebbe ritornato implicitamente, e nil è trattato come false.
|
|
|
|
{% include notice.html notice=page.cb_cmdsprivs %}
|
|
|
|
Dovresti assicurarti, poi, che il messaggio potrebbe essere un comando che invia messaggi in chat,
|
|
o che l'utente potrebbere non avere `shout`.
|
|
|
|
```lua
|
|
core.register_on_chat_message(function(name, message)
|
|
if message:sub(1, 1) == "/" then
|
|
print(name .. " ha eseguito un comando")
|
|
elseif core.check_player_privs(name, { shout = true }) then
|
|
print(name .. " ha detto " .. message)
|
|
else
|
|
print(name .. " ha provato a dire " .. message ..
|
|
" ma non ha lo shout")
|
|
end
|
|
|
|
return false
|
|
end)
|
|
```
|