IT/Introduzione allo scripting della GUI: Difference between revisions

From Multi Theft Auto: Wiki
Jump to navigation Jump to search
No edit summary
No edit summary
 
(14 intermediate revisions by 2 users not shown)
Line 1: Line 1:
{{IT/MainP}}
{{IT/MainP}}
<!-- place holder -->
[[Category:100%]]
[[Category:IT/Concetti di scripting]]
[[Category:IT/Guide e tutorial]]
Una funzionalità molto importane di MTA è quella di poter scriptare delle GUI (Graphic User Interface - Interfaccia Grafica per l'Utente) personalizzate. La GUI consiste di finestre, pulsanti, campi di modifica, caselle di controllo... Essi possono essere mostrati mentre un player sta giocando, e possono essere usati al posto dei normali comandi per l'input/output.  
Una funzionalità molto importane di MTA è quella di poter scriptare delle GUI (Graphic User Interface - Interfaccia Grafica per l'Utente) personalizzate. La GUI consiste di finestre, pulsanti, campi di modifica, caselle di controllo... Essi possono essere mostrati mentre un player sta giocando, e possono essere usati al posto dei normali comandi per l'input/output.  


Line 6: Line 8:


==Un tutorial per creare una finestra di login==
==Un tutorial per creare una finestra di login==
In questo tutorial creeremo una semplice finestra di login, con due campi ed un pulsante. La finestra appare quando un giocatore entra nel server, e quando il pulsante viene premuto, il giocatore spawna. Il tutorial continuerà la ''gamemode'' che abbiamo iniziato nell'[[introduzione allo scripting|IT/Introduzione allo Scripting]]. Daremo anche un'occhiata allo scripting lato client.  
In questo tutorial creeremo una semplice finestra di login, con due campi ed un pulsante. La finestra appare quando un giocatore entra nel server, e quando il pulsante viene premuto, il giocatore spawna. Il tutorial continuerà la ''gamemode'' che abbiamo iniziato nell'[[IT/Introduzione allo scripting|Introduzione allo Scripting]]. Daremo anche un'occhiata allo scripting lato client.  


===Disegnare la finestra===
===Disegnare la finestra===
Line 21: Line 23:
Come forse avrai notato, le coordinate che abbiamo inserito sono in percentuale, in questo caso rispetto all'intero schermo. Significa che 0 corrisponde all'estremità destra dello schermo, 1 a quella sinistra, e 0,5 la metà esatta. Questo è applicato non solo alla X e alla Y, ma anche alla larghezza e all'altezza della finestra (se "Larghezza" fosse 0.5, la finestra sarebbe larga esattamente la metà dello schermo). In seguito aggiungeremo le scritte ("username:" e "password:"), i campi di modifica e la casella di controllo. Sostituiamo la funzione con la sua versione completa:
Come forse avrai notato, le coordinate che abbiamo inserito sono in percentuale, in questo caso rispetto all'intero schermo. Significa che 0 corrisponde all'estremità destra dello schermo, 1 a quella sinistra, e 0,5 la metà esatta. Questo è applicato non solo alla X e alla Y, ma anche alla larghezza e all'altezza della finestra (se "Larghezza" fosse 0.5, la finestra sarebbe larga esattamente la metà dello schermo). In seguito aggiungeremo le scritte ("username:" e "password:"), i campi di modifica e la casella di controllo. Sostituiamo la funzione con la sua versione completa:
<syntaxhighlight lang="lua">
<syntaxhighlight lang="lua">
function CreateLoginWindow()
function CreaFinestraLogin()
local X = 0.375
local X = 0.375
local Y = 0.375
local Y = 0.375
local Width = 0.25
local Larghezza = 0.25
local Height = 0.25
local Altezza = 0.25
wdwLogin = guiCreateWindow(X, Y, Width, Height, "Please Log In", true)
wdwLogin = guiCreateWindow(X, Y, Larghezza, Altezza, "Log In", true)
 
X = 0.0825
X = 0.0825
Y = 0.2
Y = 0.2
Width = 0.25
Larghezza = 0.25
Height = 0.25
Altezza = 0.25
guiCreateLabel(X, Y, Width, Height, "Username", true, wdwLogin)
guiCreateLabel(X, Y, Larghezza, Altezza, "Username", true, wdwLogin)
Y = 0.5
Y = 0.5
guiCreateLabel(X, Y, Width, Height, "Password", true, wdwLogin)
guiCreateLabel(X, Y, Larghezza, Altezza, "Password", true, wdwLogin)
X = 0.415
X = 0.415
Y = 0.2
Y = 0.2
Width = 0.5
Larghezza = 0.5
Height = 0.15
Altezza = 0.15
edtUser = guiCreateEdit(X, Y, Width, Height, "", true, wdwLogin)
edtUser = guiCreateEdit(X, Y, Larghezza, Altezza, "", true, wdwLogin)
Y = 0.5
edtPass = guiCreateEdit(X, Y, Width, Height, "", true, wdwLogin)
        Y = 0.5
edtPass = guiCreateEdit(X, Y, Larghezza, Altezza, "", true, wdwLogin)
guiEditSetMaxLength(edtUser, 50)
guiEditSetMaxLength(edtUser, 50)
guiEditSetMaxLength(edtPass, 50)
guiEditSetMaxLength(edtPass, 50)
Line 48: Line 51:
X = 0.415
X = 0.415
Y = 0.7
Y = 0.7
Width = 0.25
Larghezza = 0.25
Height = 0.2
Altezza = 0.2
btnLogin = guiCreateButton(X, Y, Width, Height, "Log In", true, wdwLogin)
btnLogin = guiCreateButton(X, Y, Larghezza, Altezza, "Log In", true, wdwLogin)
guiSetVisible(wdwLogin, false)
guiSetVisible(wdwLogin, false)
end
end
</syntaxhighlight>
</syntaxhighlight>
Note that every GUI component created is a child of the window, this is done by specifying the parent element (wdwLogin, in this case) when creating the component:
Nota che ogni componente GUI che abbiamo creato è ''figlio'' della finestra, e per farlo abbiamo specificato l'elemento ''genitore'' (wdwLogin, in questo caso) quando abbiamo creato il componente:
<syntaxhighlight lang="lua">
<syntaxhighlight lang="lua">
guiCreateLabel(X, Y, Width, Height, "Password", true, wdwLogin)
guiCreateLabel(X, Y, Larghezza, Altezza, "Password", true, wdwLogin)
</syntaxhighlight>
</syntaxhighlight>
This is very useful because later when you need to control the entire set of GUI, you can just refer to the parent element. For example:
Questo è molto utile, perché quando in seguito dovremo controllare l'intero set di GUI, potremo riferirci direttamente all'elemento ''genitore''. Ad esempio:
<syntaxhighlight lang="lua">
<syntaxhighlight lang="lua">
guiSetVisible(wdwLogin, false) --hides all the GUI we made so we can show them to the player at the appropriate moment.  
guiSetVisible(wdwLogin, false) --nasconde tutti gli elementi GUI creati finora, perché il giocatore li veda solo al momento opportuno.  
</syntaxhighlight>
</syntaxhighlight>


===Using the function we wrote===
===Usare la funzione che abbiamo scritto===
The CreateLoginWindow function is done, but it won't do anything until we call it. It is recommended to create all GUI when the client resource starts, hide them, and show them to player later when needed. Therefore, we'll write an event handler for "[[onClientResourceStart]]" to create the window:
La funzione CreaFinestraLogin è pronta, ma sarà inutile finchè non la chiameremo. Si raccomanda di creare tutti gli elementi GUI quando lo script lato client è caricato, nasconderli, e poi mostrarli al giocatore quando serve. Pertanto, creeremo un ''event handler'' legato all'evento "[[IT/onClientResourceStart|onClientResourceStart]]" per creare la finestra:
<syntaxhighlight lang="lua">
<syntaxhighlight lang="lua">
addEventHandler("onClientResourceStart", getResourceRootElement(getThisResource()),  
addEventHandler("onClientResourceStart", getResourceRootElement(getThisResource()),  
function ()
function ()
CreateLoginWindow()
CreaFinestraLogin()
end
end
)
)
</syntaxhighlight>
</syntaxhighlight>
We would like to show the window when the client joins the game, using the same event "[[onClientResourceStart]]". Now the event handler looks like:
Vorremmo quindi che la finestra apparisse quando il giocatore entra nella partita, usando lo stesso evento "[[IT/onClientResourceStart|onClientResourceStart]]". Adesso l'''event handler'' risulterà simile a questo:
<syntaxhighlight lang="lua">
<syntaxhighlight lang="lua">
addEventHandler("onClientResourceStart", getResourceRootElement(getThisResource()),  
addEventHandler("onClientResourceStart", getResourceRootElement(getThisResource()),  
function ()
function ()
CreateLoginWindow()
CreaFinestraLogin()


                 outputChatBox("Welcome to My MTA DM Server, please log in. ")
                 outputChatBox("Benvenuto nel server, per favore effettua il login.")


        if (wdwLogin ~= nil) then
        if (wdwLogin ~= nil) then
Line 90: Line 93:
)
)
</syntaxhighlight>
</syntaxhighlight>
Note that we have a security check before making the window visible, so that in case the window had not been created, in which case wdwLogin is not a valid element, we don't get an error. The [[showCursor]] function gives control to your mouse, and [[guiSetInputEnabled]] makes sure when you type in the GUI, certain letters like "A", "S", "D", "W", "T" don't move your character or bring out the chatbox input. In the next step, we'll make the button work as desired.
Abbiamo effettuato un controllo prima di chiamare la funzione [[IT/guiSetVisible|guiSetVisible]], in modo da verificare l'esistenza di wdwLogin: anche se esso non è un elemento valido, in ogni caso non otterremo un errore. La funzione [[IT/showCursor|showCursor]] ti dà controllo sul tuo mouse, e [[IT/guiSetInputEnabled|guiSetInputEnabled]] serve ad assicurarsi che mentre stai scrivendo nella GUI, lettere come "A", "S", "D", "W", "T" non muoveranno il tuo personaggio o chiuderanno la finestra GUI. Nel prossimo passo, faremo in modo che il bottone funzioni come desideriamo.


===Scripting the button===
===Scriptare il pulsante===
When the player clicks on any part of the GUI, the event "[[onClientGUIClick]]" will be triggered for the GUI component you clicked on. For instance, if you click on the button, you can add the event handler attached to the button:
Quando il giocatore clicca su qualsiasi parte della GUI, verrà chiamato l'evento "[[IT/onClientGUIClick|onClientGUIClick]]" per il componente GUI su cui hai cliccato. Quindi, se clicchi sul pulsante, puoi aggiungere un ''event handler'' legato al pulsante:
<syntaxhighlight lang="lua">
<syntaxhighlight lang="lua">
addEventHandler("onClientGUIClick", theButtonElement, theHandlerFunction, false)
addEventHandler("onClientGUIClick", pulsante, funzione, false)
</syntaxhighlight>
</syntaxhighlight>
In our script, we only need the event handler attached to the button. When it's clicked, the client will tell the server to spawn the player. Find the event handler code for "onClientResourceStart" from the previous section, and add the following line right AFTER CreateLoginWindow() is called:
Nel nostro script, abbiamo bisogno di un ''event handler'' legato solo al pulsante. Quando viene cliccato, il client ''dirà'' al server di spawnare il player. Recuperate il codice dell'"onClientResourceStart" dalla precedente sezione, e aggiungete la linea successiva DOPO che la funzione CreaFinestraLogin() è chiamata:
<syntaxhighlight lang="lua">
<syntaxhighlight lang="lua">
addEventHandler("onClientGUIClick", btnLogin, clientSubmitLogin, false)
addEventHandler("onClientGUIClick", btnLogin, clientConfermaLogin, false)
</syntaxhighlight>
</syntaxhighlight>
The event handler must be added here because it makes sure variable btnLogin contains the actual button. You cannot attach an event to an non-existant element. You should have noticed that we need the "clientSubmitLogin" function, as stated in the line above.
L'event handler deve essere aggiunto qui perché dobbiamo essere certi che la variabile btnLogin contenga il pulsante che ci serve. Non puoi legare un evento a un elemento che non esiste. Ti sarai reso conto che abbiamo bisogno della funzione "clientConfermaLogin", come è scritto nella riga di sopra (ricordate che questa funzione va sempre PRIMA dell'''event handler'' a cui si riferisce).
<syntaxhighlight lang="lua">
<syntaxhighlight lang="lua">
function clientSubmitLogin(button)
function clientConfermaLogin(tasto)
if button == "left" then
if tasto == "left" then
triggerServerEvent("SubmitLogin", getRootElement(), guiGetText(edtUser), guiGetText(edtPass))
triggerServerEvent("ConfermaLogin", getRootElement(), guiGetText(edtUser), guiGetText(edtPass))
guiSetInputEnabled(false)
guiSetInputEnabled(false)
guiSetVisible(wdwLogin, false)
guiSetVisible(wdwLogin, false)
Line 113: Line 116:
end
end
</syntaxhighlight>
</syntaxhighlight>
The variable "button" is passed by the event handler, and it's a string with the name of the button (either "left" or "right"). Here we also hit a new concept, which is custom events. Custom events can be triggered by script from the same side (server to server, or client to client), or from the other side (server to client, or vice versa). Here we use the [[triggerServerEvent]] function to trigger a custom event on the server, "SubmitLogin".
La variabile "tasto" è passata dall'''event handler'', ed è una stringa contenente il nome del tasto del mouse premuto ("left" [sinistra] o "right" [destra]). Qui tocchiamo anche un nuovo concetto, gli eventi personalizzati. Essi possono essere chiamati dallo stesso ''lato'' (da server a server, da client a client), o possono servire da mezzo di comunicazione tra i due ''lati'' (da server a client, o viceversa). Qui usiamo la funzione [[IT/triggerServerEvent|triggerServerEvent]] per chiamare un evento personalizzato gestito dal server , "ConfermaLogin".


At this point we have all the code needed on the client side. On the server side, recall that we are spawning the player as soon as they join, as shown below:  
A questo punto abbiamo tutto il codice che ci serve, lato client. Sul lato server, ricordiamo che nella mode che abbiamo spawneremo i players nel momento in cui entrano nella partita:  
<syntaxhighlight lang="lua">
<syntaxhighlight lang="lua">
function joinHandler()
function joinHandler()
Line 124: Line 127:
spawnPlayer(source, x, y, z)
spawnPlayer(source, x, y, z)
fadeCamera(source, true)
fadeCamera(source, true)
outputChatBox("Welcome to My Server", source)
outputChatBox("Benvenuto nel mio server!", source)
end
end
addEventHandler("onPlayerJoin", getRootElement(), joinHandler)
addEventHandler("onPlayerJoin", getRootElement(), joinHandler)
</syntaxhighlight>
</syntaxhighlight>
However, since we are going to spawn the player when the button is clicked, we must replace the "onPlayerJoin" event with the custom event triggered by the client script. Replace the above code with the following:
Tuttavia, visto che dovremo spawnare il player quando il pulsante viene premuto, basterà sostituire l'evento "onPlayerJoin" con l'evento personalizzato chiamato dallo script lato client. Replace the above code with the following:
<syntaxhighlight lang="lua">
<syntaxhighlight lang="lua">
function joinHandler(username, password)
function joinHandler(username, password)
Line 135: Line 138:
y = -1714.46
y = -1714.46
z = 10
z = 10
         if (client) then
         if (source) then
      spawnPlayer(client, x, y, z)
      spawnPlayer(source, x, y, z)
      fadeCamera(client, true)
      fadeCamera(source, true)
      outputChatBox("Welcome to My Server", client)
      outputChatBox("Benvenuto nel mio server!", source)
         end
         end
end
end


addEvent("SubmitLogin", true)
addEvent("ConfermaLogin", true)
addEventHandler("SubmitLogin", getRootElement(), joinHandler)
addEventHandler("ConfermaLogin", getRootElement(), joinHandler)
</syntaxhighlight>
</syntaxhighlight>
Note that the second arguement of [[addEvent]] function (the one with value "true") specifies whether the event can be triggered by the other side, therefore we need to turn it on since the client is triggering it. Also note the variable "client", it's an internal variable used by MTA to identify the player who triggered the event.  
Nota che il secondo argomento della funzione [[IT/addEvent|addEvent]] (quello col valore "true") specifica se l'evento può essere chiamato dall'''altro lato'', ed evidentemente dobbiamo attivarlo, perché l'evento personalizzato in questo caso viene chiamato dal client. La variabile "source" in questo caso identifica il client che ha ''causato'' l'evento, cioé che ha fatto chiamare la funzione.  


Finally, do not forget to include the new gui.lua file in the meta.xml of the main resource, and label it as a client script:
Infine, non dimentichiamo di includere il nuovo file ''gui.lua'' nel ''meta.xml'' della resource principale:
<syntaxhighlight lang="xml">
<syntaxhighlight lang="xml">
<script src="client/gui.lua" type="client" />
<script src="client/gui.lua" type="client" />
</syntaxhighlight>
</syntaxhighlight>


As to this point, we have a basic login window that spawns the player when the "login" button is clicked. You can also use the username and password submitted by the [[triggerServerEvent]] function to verify the player's identify before spawning him.
A questo punto, abbiamo un semplice sistema di login che spawna il giocatore quando il pulsante "login" è premuto. Possiamo anche usare l'username e la password inviati dalla funzione [[IT/triggerServerEvent|triggerServerEvent]] per verificare l'identità del giocatore prima di spawnarlo.
 
[[en:Introduction to Scripting the GUI]]
[[ru:Introduction to Scripting the GUI]]

Latest revision as of 14:47, 22 June 2009

« Torna alla Pagina principale italiana .

Una funzionalità molto importane di MTA è quella di poter scriptare delle GUI (Graphic User Interface - Interfaccia Grafica per l'Utente) personalizzate. La GUI consiste di finestre, pulsanti, campi di modifica, caselle di controllo... Essi possono essere mostrati mentre un player sta giocando, e possono essere usati al posto dei normali comandi per l'input/output.

GUI del pannello da Admin

Un tutorial per creare una finestra di login

In questo tutorial creeremo una semplice finestra di login, con due campi ed un pulsante. La finestra appare quando un giocatore entra nel server, e quando il pulsante viene premuto, il giocatore spawna. Il tutorial continuerà la gamemode che abbiamo iniziato nell'Introduzione allo Scripting. Daremo anche un'occhiata allo scripting lato client.

Disegnare la finestra

Tutte le GUI devono essere scriptate lato client, dunque potrebbe essere conveniente riunirle tutte in una cartella separata. Dunque, quando hai creato una cartella a tuo piacimento, creiamo un file "gui.lua", e in questo file scriveremo una funzione che disegni la finestra:

function CreaFinestraLogin()
	local X = 0.375
	local Y = 0.375
	local Larghezza = 0.25
	local Altezza = 0.25
	wdwLogin = guiCreateWindow(X, Y, Larghezza, Altezza, "Log In", true)
end

Come forse avrai notato, le coordinate che abbiamo inserito sono in percentuale, in questo caso rispetto all'intero schermo. Significa che 0 corrisponde all'estremità destra dello schermo, 1 a quella sinistra, e 0,5 la metà esatta. Questo è applicato non solo alla X e alla Y, ma anche alla larghezza e all'altezza della finestra (se "Larghezza" fosse 0.5, la finestra sarebbe larga esattamente la metà dello schermo). In seguito aggiungeremo le scritte ("username:" e "password:"), i campi di modifica e la casella di controllo. Sostituiamo la funzione con la sua versione completa:

function CreaFinestraLogin()
	local X = 0.375
	local Y = 0.375
	local Larghezza = 0.25
	local Altezza = 0.25
	wdwLogin = guiCreateWindow(X, Y, Larghezza, Altezza, "Log In", true)

	X = 0.0825
	Y = 0.2
	Larghezza = 0.25
	Altezza = 0.25
	guiCreateLabel(X, Y, Larghezza, Altezza, "Username", true, wdwLogin)
	Y = 0.5
	guiCreateLabel(X, Y, Larghezza, Altezza, "Password", true, wdwLogin)
	
	X = 0.415
	Y = 0.2
	Larghezza = 0.5
	Altezza = 0.15
	edtUser = guiCreateEdit(X, Y, Larghezza, Altezza, "", true, wdwLogin)
	
        Y = 0.5
	edtPass = guiCreateEdit(X, Y, Larghezza, Altezza, "", true, wdwLogin)
	guiEditSetMaxLength(edtUser, 50)
	guiEditSetMaxLength(edtPass, 50)
	
	X = 0.415
	Y = 0.7
	Larghezza = 0.25
	Altezza = 0.2
	btnLogin = guiCreateButton(X, Y, Larghezza, Altezza, "Log In", true, wdwLogin)
	
	guiSetVisible(wdwLogin, false)
end

Nota che ogni componente GUI che abbiamo creato è figlio della finestra, e per farlo abbiamo specificato l'elemento genitore (wdwLogin, in questo caso) quando abbiamo creato il componente:

guiCreateLabel(X, Y, Larghezza, Altezza, "Password", true, wdwLogin)

Questo è molto utile, perché quando in seguito dovremo controllare l'intero set di GUI, potremo riferirci direttamente all'elemento genitore. Ad esempio:

guiSetVisible(wdwLogin, false) --nasconde tutti gli elementi GUI creati finora, perché il giocatore li veda solo al momento opportuno. 

Usare la funzione che abbiamo scritto

La funzione CreaFinestraLogin è pronta, ma sarà inutile finchè non la chiameremo. Si raccomanda di creare tutti gli elementi GUI quando lo script lato client è caricato, nasconderli, e poi mostrarli al giocatore quando serve. Pertanto, creeremo un event handler legato all'evento "onClientResourceStart" per creare la finestra:

addEventHandler("onClientResourceStart", getResourceRootElement(getThisResource()), 
	function ()
		CreaFinestraLogin()
	end
)	

Vorremmo quindi che la finestra apparisse quando il giocatore entra nella partita, usando lo stesso evento "onClientResourceStart". Adesso l'event handler risulterà simile a questo:

addEventHandler("onClientResourceStart", getResourceRootElement(getThisResource()), 
	function ()
		CreaFinestraLogin()

                outputChatBox("Benvenuto nel server, per favore effettua il login.")

	        if (wdwLogin ~= nil) then
		         guiSetVisible(wdwLogin, true)
	        end 

	        showCursor(true)
	        guiSetInputEnabled(true)
	end
)	

Abbiamo effettuato un controllo prima di chiamare la funzione guiSetVisible, in modo da verificare l'esistenza di wdwLogin: anche se esso non è un elemento valido, in ogni caso non otterremo un errore. La funzione showCursor ti dà controllo sul tuo mouse, e guiSetInputEnabled serve ad assicurarsi che mentre stai scrivendo nella GUI, lettere come "A", "S", "D", "W", "T" non muoveranno il tuo personaggio o chiuderanno la finestra GUI. Nel prossimo passo, faremo in modo che il bottone funzioni come desideriamo.

Scriptare il pulsante

Quando il giocatore clicca su qualsiasi parte della GUI, verrà chiamato l'evento "onClientGUIClick" per il componente GUI su cui hai cliccato. Quindi, se clicchi sul pulsante, puoi aggiungere un event handler legato al pulsante:

addEventHandler("onClientGUIClick", pulsante, funzione, false)

Nel nostro script, abbiamo bisogno di un event handler legato solo al pulsante. Quando viene cliccato, il client dirà al server di spawnare il player. Recuperate il codice dell'"onClientResourceStart" dalla precedente sezione, e aggiungete la linea successiva DOPO che la funzione CreaFinestraLogin() è chiamata:

addEventHandler("onClientGUIClick", btnLogin, clientConfermaLogin, false)

L'event handler deve essere aggiunto qui perché dobbiamo essere certi che la variabile btnLogin contenga il pulsante che ci serve. Non puoi legare un evento a un elemento che non esiste. Ti sarai reso conto che abbiamo bisogno della funzione "clientConfermaLogin", come è scritto nella riga di sopra (ricordate che questa funzione va sempre PRIMA dell'event handler a cui si riferisce).

function clientConfermaLogin(tasto)
	if tasto == "left" then
		
		triggerServerEvent("ConfermaLogin", getRootElement(), guiGetText(edtUser), guiGetText(edtPass))
		guiSetInputEnabled(false)
		guiSetVisible(wdwLogin, false)
		showCursor(false)
	end
end

La variabile "tasto" è passata dall'event handler, ed è una stringa contenente il nome del tasto del mouse premuto ("left" [sinistra] o "right" [destra]). Qui tocchiamo anche un nuovo concetto, gli eventi personalizzati. Essi possono essere chiamati dallo stesso lato (da server a server, da client a client), o possono servire da mezzo di comunicazione tra i due lati (da server a client, o viceversa). Qui usiamo la funzione triggerServerEvent per chiamare un evento personalizzato gestito dal server , "ConfermaLogin".

A questo punto abbiamo tutto il codice che ci serve, lato client. Sul lato server, ricordiamo che nella mode che abbiamo spawneremo i players nel momento in cui entrano nella partita:

function joinHandler()
	local x,y,z
	x = 1959.55
	y = -1714.46
	z = 10
	spawnPlayer(source, x, y, z)
	fadeCamera(source, true)
	outputChatBox("Benvenuto nel mio server!", source)
end
addEventHandler("onPlayerJoin", getRootElement(), joinHandler)

Tuttavia, visto che dovremo spawnare il player quando il pulsante viene premuto, basterà sostituire l'evento "onPlayerJoin" con l'evento personalizzato chiamato dallo script lato client. Replace the above code with the following:

function joinHandler(username, password)
	local x,y,z
	x = 1959.55
	y = -1714.46
	z = 10
        if (source) then
	      spawnPlayer(source, x, y, z)
	      fadeCamera(source, true)
	      outputChatBox("Benvenuto nel mio server!", source)
        end
end

addEvent("ConfermaLogin", true)
addEventHandler("ConfermaLogin", getRootElement(), joinHandler)

Nota che il secondo argomento della funzione addEvent (quello col valore "true") specifica se l'evento può essere chiamato dall'altro lato, ed evidentemente dobbiamo attivarlo, perché l'evento personalizzato in questo caso viene chiamato dal client. La variabile "source" in questo caso identifica il client che ha causato l'evento, cioé che ha fatto chiamare la funzione.

Infine, non dimentichiamo di includere il nuovo file gui.lua nel meta.xml della resource principale:

<script src="client/gui.lua" type="client" />

A questo punto, abbiamo un semplice sistema di login che spawna il giocatore quando il pulsante "login" è premuto. Possiamo anche usare l'username e la password inviati dalla funzione triggerServerEvent per verificare l'identità del giocatore prima di spawnarlo.