<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.multitheftauto.com/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=IamDenny</id>
	<title>Multi Theft Auto: Wiki - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.multitheftauto.com/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=IamDenny"/>
	<link rel="alternate" type="text/html" href="https://wiki.multitheftauto.com/wiki/Special:Contributions/IamDenny"/>
	<updated>2026-04-05T21:02:42Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.39.3</generator>
	<entry>
		<id>https://wiki.multitheftauto.com/index.php?title=%D0%92%D0%B2%D0%B5%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D0%B2_%D1%81%D0%BA%D1%80%D0%B8%D0%BF%D1%82%D0%B8%D0%BD%D0%B3_GUI&amp;diff=66011</id>
		<title>Введение в скриптинг GUI</title>
		<link rel="alternate" type="text/html" href="https://wiki.multitheftauto.com/index.php?title=%D0%92%D0%B2%D0%B5%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D0%B2_%D1%81%D0%BA%D1%80%D0%B8%D0%BF%D1%82%D0%B8%D0%BD%D0%B3_GUI&amp;diff=66011"/>
		<updated>2020-04-26T09:38:42Z</updated>

		<summary type="html">&lt;p&gt;IamDenny: /* Вызов сервера */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;!-- place holder --&amp;gt;&lt;br /&gt;
Одной из важных особенностей MTA:SA является возможность программирования настраиваемого GUI (Graphic User Interface, графического интерфейса пользователя). GUI состоит из окон, кнопок, редактируемых полей, флажков... Практически всех стандартных компонентов для заполнения форм в графических средах. Они могут отображаться пока пользователь в игре и используются для ввода и вывода вместо привычных команд чата. &lt;br /&gt;
&lt;br /&gt;
[[Image:AdminGUI.png|thumb|GUI Admin Console]]&lt;br /&gt;
&lt;br /&gt;
==Руководство по созданию окна авторизации==&lt;br /&gt;
В этом руководстве мы сделаем простое окно запроса логина с двумя полями для ввода и одной кнопкой. Окно будет появляться при подключении игрока к серверу, а по нажатии на кнопку он заспавнится. Руководство продолжит мод, созданный нами во [[Введение в скриптинг|введении в скриптинг]] ''(Если вы пользовались [[Введение в скриптинг|введением в скриптинг]], вам понадобится убрать или закомментировать в коде строчку со [[spawnPlayer]] в функции &amp;quot;joinHandler&amp;quot;, так как в данном руководстве мы заменим ее альтернативой с gui)''. Мы также ознакомимся со скриптингом на клиентской стороне. &lt;br /&gt;
&lt;br /&gt;
===Отрисовка окна===&lt;br /&gt;
Все GUI обязательно делаются на клиентской стороне. Это также может являться хорошей практикой хранения всех клиентских скриптов в отдельной папке. &lt;br /&gt;
&lt;br /&gt;
Переместитесь в директорию /ваш MTA Server/mods/deathmatch/resources/myserver/ и создайте папку с названием &amp;quot;client&amp;quot;. В директории /client/ создайте текстовый файл и назовите его &amp;quot;gui.lua&amp;quot;. &lt;br /&gt;
&lt;br /&gt;
В этом файле мы напишем функцию, которая будет отрисовывать окно. Для создания окна мы воспользуемся [[guiCreateWindow]]:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
function createLoginWindow()&lt;br /&gt;
	-- определяем позиции окна по осям X и Y&lt;br /&gt;
	local X = 0.375&lt;br /&gt;
	local Y = 0.375&lt;br /&gt;
	-- объявляем ширину и высоту окна&lt;br /&gt;
	local Width = 0.25&lt;br /&gt;
	local Height = 0.25&lt;br /&gt;
	-- создаем окно и сохраняем значение его элемента в переменной 'wdwLogin'&lt;br /&gt;
	-- кликаем по имени функции, чтобы прочитать ее документацию&lt;br /&gt;
	wdwLogin = guiCreateWindow(X, Y, Width, Height, &amp;quot;Пожалуйста, залогиньтесь&amp;quot;, true)&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Относительные и абсолютные===&lt;br /&gt;
Заметьте, что последний аргумент, передаваемый guiCreateWindow в образце выше, ''true''. Это говорит о том, что координаты и габариты окна - '''относительны''', значит, измеряются в ''процентах'' от всего размера экрана. То есть если верхний левый угол экрана - это 0, а верхний правый - это 1, то позиция 0.5 по оси X является центром экрана по горизонтали. Аналогично этому, если вершина экрана - это 0, а низ - это 1, то позиция 0.2 по оси Y будет отступом на 20% всей высоты от верхней границы экрана. Те же принципы применимы к ширине и высоте (при Width, равной 0.5, окно будет шириной с пол-экрана).&lt;br /&gt;
&lt;br /&gt;
Альтернативно использованию относительных значений, можно использовать '''абсолютные''' (указав ''false'' вместо true в guiCreateWindow). Абсолютные значения вычисляются как конкретное количество пикселей от верхнего левого угла родительского элемента (если родительским не указан никакой gui-элемент, то родителем является экран сам по себе). Если разрешением экрана является, допустим, 1920x1200, то верхняя левая сторона экрана будет 0 пикселями, а верхняя правая - 1920 пикселями, позиция 960 по оси X же будет являться центром экрана по горизонтали. Аналогично этому, если вершина экрана - это 0 пикселей, а низ - 1200, то позиция 20 по оси Y будет отступом на 20 пикселей от верхней границы экрана. Те же принципы применимы к ширине и высоте (при Width, равной 50, окно будет 50 пикселей в ширину). ''Вы можете пользоваться [[guiGetScreenSize]] и путем нехитрых вычислений получать нужные вам абсолютные значения.''&lt;br /&gt;
&lt;br /&gt;
Разница между использованием относительных и абсолютных значений очевидна: gui, созданное с использованием абсолютных значений, всегда будет появляться с точь-в-точь одинаковыми габаритами и позицией, в то время как gui, созданное с использованием относительных значений, всегда будет связано процентным соотношением с размерами своего родителя.&lt;br /&gt;
&lt;br /&gt;
Абсолютные значения в целом легче поддерживать при ручной правке кода, но выбор типа используемых значений варьируется от ситуации к ситуации.&lt;br /&gt;
&lt;br /&gt;
Для разрешения целей из данного руководства мы будет пользоваться относительными значениями.&lt;br /&gt;
&lt;br /&gt;
===Добавление компонентов===&lt;br /&gt;
Теперь мы добавим текстовые метки (называющиеся &amp;quot;логин:&amp;quot; и &amp;quot;пароль:&amp;quot;), редактируемые поля (для ввода информации) и кнопку для непосредственного залогинивания.&lt;br /&gt;
&lt;br /&gt;
Для создания кнопок воспользуемся [[guiCreateButton]], а для создания редактируемых полей - [[guiCreateEdit]]:&lt;br /&gt;
&lt;br /&gt;
'''Примите во внимание, что сейчас мы просто дописываем уже существующую функцию 'createLoginWindow'. Функция ниже не является новой, а предназначена заменить то, что мы уже имеем.''' &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
function createLoginWindow()&lt;br /&gt;
	local X = 0.375&lt;br /&gt;
	local Y = 0.375&lt;br /&gt;
	local Width = 0.25&lt;br /&gt;
	local Height = 0.25&lt;br /&gt;
	wdwLogin = guiCreateWindow(X, Y, Width, Height, &amp;quot;Пожалуйста, залогиньтесь&amp;quot;, true)&lt;br /&gt;
	&lt;br /&gt;
	-- объявляем новые позиции для первой метки по осям X и Y&lt;br /&gt;
	X = 0.0825&lt;br /&gt;
	Y = 0.2&lt;br /&gt;
	-- объявляем новые значения ширины и высоты для первой метки&lt;br /&gt;
	Width = 0.25&lt;br /&gt;
	Height = 0.25&lt;br /&gt;
	-- создаем первую метку, заметьте, что последний указанный аргумент - 'wdwLogin', значит окно,&lt;br /&gt;
	-- созданное выше, является родителем этой метки (так что значения ее позиции и габариты теперь связаны с позицией того окна)&lt;br /&gt;
	guiCreateLabel(X, Y, Width, Height, &amp;quot;Имя&amp;quot;, true, wdwLogin)&lt;br /&gt;
	-- изменяем позицию по оси Y, чтобы вторая метка была чуть ниже первой&lt;br /&gt;
	Y = 0.5&lt;br /&gt;
	guiCreateLabel(X, Y, Width, Height, &amp;quot;Пароль&amp;quot;, true, wdwLogin)&lt;br /&gt;
	&lt;br /&gt;
&lt;br /&gt;
	X = 0.415&lt;br /&gt;
	Y = 0.2&lt;br /&gt;
	Width = 0.5&lt;br /&gt;
	Height = 0.15&lt;br /&gt;
	edtUser = guiCreateEdit(X, Y, Width, Height, &amp;quot;&amp;quot;, true, wdwLogin)&lt;br /&gt;
	Y = 0.5&lt;br /&gt;
	edtPass = guiCreateEdit(X, Y, Width, Height, &amp;quot;&amp;quot;, true, wdwLogin)&lt;br /&gt;
	-- для логина и пароля устанавливаем ограничение на максимальное количество введенных символов 50&lt;br /&gt;
	guiEditSetMaxLength(edtUser, 50)&lt;br /&gt;
	guiEditSetMaxLength(edtPass, 50)&lt;br /&gt;
	&lt;br /&gt;
	X = 0.415&lt;br /&gt;
	Y = 0.7&lt;br /&gt;
	Width = 0.25&lt;br /&gt;
	Height = 0.2&lt;br /&gt;
	btnLogin = guiCreateButton(X, Y, Width, Height, &amp;quot;Логин&amp;quot;, true, wdwLogin)&lt;br /&gt;
	&lt;br /&gt;
	-- делаем окно невидимым&lt;br /&gt;
	guiSetVisible(wdwLogin, false)&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Заметьте, что каждый созданный компонент GUI является дочерним по отношению к окну, это сделано благодаря указанию родительского элемента (в данном случае, wdwLogin) при создании компонента. &lt;br /&gt;
&lt;br /&gt;
Это очень полезно не только потому что все компоненты прикреплены к окну и будут двигаться вместе с ним, но и так как любые изменения с &amp;quot;родительским&amp;quot; окном будут применены дальше вниз по дереву к этим дочерним компонентам. Например, мы теперь можем спрятать весь только что созданный GUI просто спрятав окно:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
guiSetVisible(wdwLogin, false) --прячет весь сделанный нами GUI, чтобы мы могли показать его игроку в соответствующий момент. &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Для редактироования GUI вы также можете воспользоваться [[RU/Resource:GUI_Editor|GUI редактором]].&lt;br /&gt;
&lt;br /&gt;
===Использование написанной функции===&lt;br /&gt;
Теперь функция createLoginWindow доделана, но пока мы ее не вызовем, она сама по себе ничего не будет делать. Рекомендуется создавать весь GUI при старте клиентского ресурса, прятать его, а затем показывать игроку, когда понадобится. Следовательно, для создания окна мы напишем обработчик события &amp;quot;[[onClientResourceStart]]&amp;quot;:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
-- прикрепляем обработчик события в корневому (root) элементу ресурса&lt;br /&gt;
-- это значит, что он сработает только при старте этого ресурса&lt;br /&gt;
addEventHandler(&amp;quot;onClientResourceStart&amp;quot;, getResourceRootElement(getThisResource()), &lt;br /&gt;
	function ()&lt;br /&gt;
		createLoginWindow()&lt;br /&gt;
	end&lt;br /&gt;
)	&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Так как это - окно входа пользователя, теперь нам надо показывать его при подключении игроков к серверу. &lt;br /&gt;
Это можно сделать, используя все то же событие, &amp;quot;[[onClientResourceStart]]&amp;quot;, мы можем изменить код выше, включив показ окна:&lt;br /&gt;
&lt;br /&gt;
'''Заметьте, что сейчас мы допишем код для уже существующего обработчика 'onClientResourceStart'. Это не новый обработчик события, код предназначен заменить то, что мы уже имеем.''' &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
addEventHandler(&amp;quot;onClientResourceStart&amp;quot;, getResourceRootElement(getThisResource()), &lt;br /&gt;
	function ()&lt;br /&gt;
		-- создаем окно входа и его компоненты&lt;br /&gt;
		createLoginWindow()&lt;br /&gt;
&lt;br /&gt;
		-- выводим игроку краткое приветствие&lt;br /&gt;
                outputChatBox(&amp;quot;Добро пожаловать на мой MTA:SA сервер, пожалуйста, залогиньтесь.&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
		-- если GUI был создан успешно, показать его игроку&lt;br /&gt;
	        if (wdwLogin ~= nil) then&lt;br /&gt;
			guiSetVisible(wdwLogin, true)&lt;br /&gt;
		else&lt;br /&gt;
			-- если GUI не был создан успешно, сообщаем игроку об этом&lt;br /&gt;
			outputChatBox(&amp;quot;Возникла непредвиденная ошибка и GUI входа не был создан.&amp;quot;)&lt;br /&gt;
	        end &lt;br /&gt;
&lt;br /&gt;
		-- активируем курсор игрока (чтобы он мог выбирать компонентф и кликать по ним)&lt;br /&gt;
	        showCursor(true)&lt;br /&gt;
		-- отдаем контроль над клавиатурой GUI, позволяя игрокам (например) нажимать 'T', не открывая при этом одновременно чат&lt;br /&gt;
	        guiSetInputEnabled(true)&lt;br /&gt;
	end&lt;br /&gt;
)	&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Заметьте, что перед тем, как сделать окно видимым, имеет место простая проверка, так что даже при маловероятном случае, когда окно не будет создано в силу того, что wdwLogin - недействительный элемент, мы не получим ошибку и проинформируем игрока о произошедшем. &lt;br /&gt;
Следующий шаг -  создание кнопочного функционала для кнопки логина.&lt;br /&gt;
&lt;br /&gt;
==Программирование кнопки==&lt;br /&gt;
Теперь мы создали GUI и явили его игроку, сейчас же надо сделать его рабочим. &lt;br /&gt;
&lt;br /&gt;
===Обнаружение клика===&lt;br /&gt;
Когда игрок кликает по какому-либо компоненту GUI, по отношении к этому компоненту срабатывает событие &amp;quot;[[onClientGUIClick]]&amp;quot;. Это позволяет нам с легкостью отслеживать различные клики по тем элементам GUI, которые мы желаем использовать.&lt;br /&gt;
Например, мы можем прикрепить событие ко кнопке btnLogin для отслеживания кликов по ней:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
-- прикрепляем событие onClientGUIClick к btnLogin и с него переключение на функцию 'clientSubmitLogin'&lt;br /&gt;
addEventHandler(&amp;quot;onClientGUIClick&amp;quot;, btnLogin, clientSubmitLogin, false)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
'''Заметьте, что последний аргумент - &amp;quot;false&amp;quot;. Это говорит о том, что срабатывание события произойдет только именно от btnLogin, но не в результате его распространения вверх или вниз по дереву. Использование &amp;quot;true&amp;quot; при прикреплении к элементам gui повлечет за собой срабатывание события при клике по любому из элементов одной ветви.'''&lt;br /&gt;
&lt;br /&gt;
Теперь эта строка кода может быть добавлена внутрь функции createLoginWindow. Распространенной ошибкой является пробовать и прикреплять события к несуществующим элементам GUI, так что всегда проверяйте, прикрепили ли вы свои события уже '''после''' создания элемента gui (в данном случае, кнопки):&lt;br /&gt;
&lt;br /&gt;
'''Обратите внимание, что сейчас мы допишем код для уже существующей функции 'createLoginWindow'.''' &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
function createLoginWindow()&lt;br /&gt;
	-- создаем все наши элементы GUI&lt;br /&gt;
	...&lt;br /&gt;
&lt;br /&gt;
	-- теперь добавим событие onClientGUIClick к свежесозданной кнопке&lt;br /&gt;
	addEventHandler(&amp;quot;onClientGUIClick&amp;quot;, btnLogin, clientSubmitLogin, false)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Управление кликом===&lt;br /&gt;
Теперь мы можем обнаружить клик игрока по кнопке, и нам нужно написать код, отвечающий за происходящее после него.&lt;br /&gt;
В нашем обработчике события [[onClientGUIClick]] мы распорядились переключаться на функцию clientSubmitLogin при клике по btnLogin.&lt;br /&gt;
Следовательно, теперь мы можем воспользоваться функцией clientSubmitLogin для контроля над происходящим после клика по кнопке:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
-- создаем функцию и определяем параметры 'button' и 'state'&lt;br /&gt;
-- (которые автоматически передаются событием onClientGUIClick)&lt;br /&gt;
function clientSubmitLogin(button,state)&lt;br /&gt;
	-- если клик по кнопке был произведен левой кнопкой мыши, и положение кнопки мыши - &amp;quot;вверху&amp;quot; (отпущена)&lt;br /&gt;
	if button == &amp;quot;left&amp;quot; and state == &amp;quot;up&amp;quot; then&lt;br /&gt;
		-- отдаем контроль над клавиатурой обратно игре (позволяя игрокам передвигаться, писать в чат и т.д.)&lt;br /&gt;
		guiSetInputEnabled(false)&lt;br /&gt;
		-- прячем окно и все его компоненты&lt;br /&gt;
		guiSetVisible(wdwLogin, false)&lt;br /&gt;
		-- прячем курсор мыши&lt;br /&gt;
		showCursor(false)&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Теперь, когда по кнопке кликнули, окно будет спрятано и все управление будет передано обратно в руки игрока. Затем, мы скажем серверу, что игрокам можно спавниться.&lt;br /&gt;
&lt;br /&gt;
===Вызов сервера===&lt;br /&gt;
Вызов сервера производится с помощью [[triggerServerEvent]]. Это позволяет вам вызывать указанное серверное событие из клиента. С помощью [[triggerClientEvent]] можно сделать и наоборот.&lt;br /&gt;
В данном случае мы будем использовать функцию [[triggerServerEvent]] для вызова созданного нами сами серверного события, названного &amp;quot;submitLogin&amp;quot;, которое затем проконтроллирует респавн игрока на серверной стороне.&lt;br /&gt;
&lt;br /&gt;
'''Примите во внимание, что сейчас мы просто дописываем код для уже существующей функции 'clientSubmitLogin'. Функция ниже не является новой, а предназначена заменить то, что мы уже имеем.''' &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
function clientSubmitLogin(button,state)&lt;br /&gt;
	if button == &amp;quot;left&amp;quot; and state == &amp;quot;up&amp;quot; then&lt;br /&gt;
		-- получаем текст, введенный в поле 'username'&lt;br /&gt;
		local username = guiGetText(edtUser)&lt;br /&gt;
		-- получаем текст, введенный в поле 'password'&lt;br /&gt;
		local password = guiGetText(edtPass)&lt;br /&gt;
&lt;br /&gt;
		-- если и username, и password существуют&lt;br /&gt;
		if username ~= &amp;quot;&amp;quot; and password ~= &amp;quot;&amp;quot; then&lt;br /&gt;
			-- вызвать серверное событие 'submitLogin', передав ему username и password&lt;br /&gt;
			triggerServerEvent(&amp;quot;submitLogin&amp;quot;, getRootElement(), username, password)&lt;br /&gt;
&lt;br /&gt;
			-- прячем gui, курсор и возвращаем управление игроку&lt;br /&gt;
			guiSetInputEnabled(false)&lt;br /&gt;
			guiSetVisible(wdwLogin, false)&lt;br /&gt;
			showCursor(false)&lt;br /&gt;
		else&lt;br /&gt;
			-- иначе выводим игроку сообщение, но не отсылаем информацию на сервер&lt;br /&gt;
			-- и не прячем gui&lt;br /&gt;
			outputChatBox(&amp;quot;Пожалуйста, введите логин и пароль.&amp;quot;)&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Создание серверного события===&lt;br /&gt;
На данный момент мы имеем весь нужный код для клиентской стороны, так что откройте ваш серверный файл 'script.lua' (из [[Введение в скриптинг|введения в скриптинг]]), либо любой другой подходящий для работы серверный файл.&lt;br /&gt;
&lt;br /&gt;
На стороне сервера надо сделать так, чтобы игрок спавнился, как только залогинится.&lt;br /&gt;
Итак, для начала нам понадобится объявить свое событие, которым мы ранее пользовались на клиенте. Это можно сделать с помощью связки [[addEvent]] и [[addEventHandler]].&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
-- создаем функцию loginHandler с параметрами username и password (переданные от gui на клиенте)&lt;br /&gt;
function loginHandler(username,password)&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- объявляем свое событие и позволяем ему быть вызванным из клиента ('true')&lt;br /&gt;
addEvent(&amp;quot;submitLogin&amp;quot;,true)&lt;br /&gt;
-- добавляем обработчик события, чтобы при вызове submitLogin происходило переключение на функцию loginHandler&lt;br /&gt;
addEventHandler(&amp;quot;submitLogin&amp;quot;,root,loginHandler)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Залогинивание===&lt;br /&gt;
Теперь у нас есть функция, которая вызывается через наше собственное событие 'submitLogin', теперь можно начать работать над процессом залогинивания и респавна игрока, задействовав функцию 'loginHandler':&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
function loginHandler(username,password)&lt;br /&gt;
	-- проверяем username и password на правильность&lt;br /&gt;
	if username == &amp;quot;user&amp;quot; and password == &amp;quot;apple&amp;quot; then&lt;br /&gt;
		-- игрок успешно залогинился, так что спавним его&lt;br /&gt;
		if (client) then&lt;br /&gt;
			spawnPlayer(client, 1959.55, -1714.46, 10)&lt;br /&gt;
			fadeCamera(client, true)&lt;br /&gt;
                        setCameraTarget(client, client)&lt;br /&gt;
			outputChatBox(&amp;quot;Добро пожаловать на мой сервер.&amp;quot;, client)&lt;br /&gt;
		end&lt;br /&gt;
	else&lt;br /&gt;
		-- если username или password неправильны, выводим игроку соответствующее сообщение&lt;br /&gt;
		outputChatBox(&amp;quot;Неправильные логин и пароль. Пожалуйста, переподсоединитесь и попробуйте еще раз.&amp;quot;,client)&lt;br /&gt;
        end			&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
addEvent(&amp;quot;submitLogin&amp;quot;,true)&lt;br /&gt;
addEventHandler(&amp;quot;submitLogin&amp;quot;,root,loginHandler)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
'''Для целей данного руководства была использована очень простая система хранения логинов/паролей. Более вменяемыми альтернативами являются встроенная система аккаунтов и база данных MySQL.'''&lt;br /&gt;
&lt;br /&gt;
Также заметьте, что была задействована переменная &amp;quot;client&amp;quot;, это - внутренняя перменная, используемая MTA для идентификации игрока, вызвавшего срабатывание события. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Наконец, не забудьте включить новый файл gui.lua в meta.xml главного ресурса и отметить его как клиентский скрипт:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;script src=&amp;quot;client/gui.lua&amp;quot; type=&amp;quot;client&amp;quot; /&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Теперь у нас есть базовое окно авторизации, проверяющее логин и пароль игрока по нажатии на кнопку залогинивания. Если они верны, игрок автоматически заспавнится.&lt;br /&gt;
&lt;br /&gt;
Для дальнейшей помощи по GUI, посетите [[:Category:GUI_Tutorials|страницу с руководствами по GUI]].&lt;br /&gt;
&lt;br /&gt;
[[Category:GUI_Tutorials]]&lt;br /&gt;
[[en:Introduction to Scripting the GUI]]&lt;br /&gt;
[[es:Introducción a la Programación de GUI]]&lt;br /&gt;
[[fr:Introduction GUI]]&lt;br /&gt;
[[it:Introduzione_allo_scripting_della_GUI]]&lt;br /&gt;
[[pt-br:Introducao ao GUI scripting]]&lt;/div&gt;</summary>
		<author><name>IamDenny</name></author>
	</entry>
</feed>