PDA

Просмотр полной версии : [Мануал] Используем URL-Изображение



TrezeLurese
28.08.2014, 14:08
Приветствую всех пользователей Pro-Pawn.
Данный небольшой урок я посвящаю одной из прекрасных возможностей MTA SA - загрузка изображения из сети.

Для чего это может пригодиться?
Ну например вы можете сохранить на хостинге картинок какой-то скрин из игры, и тут же отправить его пользователю прямо в игре, или в случае игровой операционной системы - изображение рабочего стола. Ну это конечно при условии, что на сервере поддерживается загрузка изображений (например как в Lunix OS 2014).

Что вам понадобится?
1) MTA SA + Сервер (при установке можно выбрать установку сервера, по умолчанию - устанавливается)
2) Текстовый редактор, или Lua редактор.
3) Ручки из правильного места.

И так, приступим.

Для начала мы создадим папку с названием ресурса (на латинице, конечно, и без пробелов) в папке ресурсов (MTA San Andreas Ver/server/mods/deathmatch/resources). Мне подойдет название "urlimg" (по этому названию мы и будем загружать ресурс)
http://i.imgur.com/uz54nyY.png

Теперь мы можем указать, что данная папка является ресурсом. Открываем редактор, и вводим в него данные строчки:

<meta>
<info author="UserName" name="URL Image" version="1" type="script"/>
</meta>
Где author - ник автора (в кавычках), name - название ресурса (может быть любое, название папки не зависит от него), version - версия ресурса, и type - тип ресурса (желательно указать "script", потому что может быть ещё и "gamemode" - игровой режим, и "map" - карта)
И сохраняем в папке "urlimg", называя файл meta.xml (но данный файл не закрываем, так как нам через него ещё и скрипт загружать)
http://i.imgur.com/CJ0zhId.png

Теперь перейдём к скрипту.
Нам нужно будет создать 2 lua файла. Один будет работать на стороне клиента, второй на стороне сервера.

Приступим.
Для начала начнём со стороны клиента.

Давайте определимся, что нам нужно?
1) Выделить место для загрузки изображения на экране.
2) Отправить запрос о предоставлении изображения.
3) Получить изображение.
4) Загрузить изображение.

Давайте выделим область для загрузки изображения. Для этого воспользуемся клиентсайдной функцией dxDrawImage (https://wiki.multitheftauto.com/wiki/DxDrawImage)
Так как данная функция работает только с onClientRender (куда мы её и поместим), обновлять данные она может только переменными.

Открываем редактор и создаём новый файл (При использовании MTA SE, ставим галочку "client-side").
Записываем в него данный код:


local image = 0 --Создаём переменную для хранения изображения
addEventHandler("onClientRender", getRootElement(), --Данное событие обновляется много раз за секунду, и будет выполняться от запуска сервера до его отключения
function() --Выполним функцию:
if image == 0 then return 1 end --Если переменная обнулена, изображение не рисовать
dxDrawImage(100, 200, 640, 480, image) --Нарисуем изображение на позиции {100, 200} с размером {640, 480} (можете подстраивать любые значения)
end)

Данный код при старте сервера ничего не нарисует, так как изображение не задано.
[Вы можете обозначить позицию и размер переменными, чтобы у вас была возможность редактировать данные значения]
Сохраняем это в папке "urlimg" с любым названием и форматом ".lua". Только не забудьте, что данный файл - клиентский.
http://i.imgur.com/PNkHqfO.png

Область изображению мы выделили.
Теперь будем выполнять запрос о получении изображения из сети. Воспользуемся функцией fetchRemote (https://wiki.multitheftauto.com/wiki/FetchRemote)
Создадим ещё один файл, на этот раз серверный, и внесём туда данный код:

function remoteFunction(responce, errno, player) --Создаём функцию, в которой будем отправлять изображение на клиент
if errno == 0 then --Проверяем параметры ссылки
triggerClientEvent(player, "sendImageToClient", root, responce) --Отправляем триггер "sendImageToClient" на клиент, содержащий в себе изображение (responce)
end
end

function loadImageByURL(url, player) --Создаём функцию, в которой отправляем запрос
fetchRemote(url, remoteFunction, false, player) --Отправляем запрос на получение изображения, с последующим выполнением функции remoteFunction
end
Отправленный триггер пока ничего не даст кроме ошибки, что событие не добавлено. Исправим чуть позже.
Сохраняем данный файл в папке "urlimg" с любым названием и форматом ".lua". Только не забудьте, что данный файл - серверный.
http://i.imgur.com/CjP63jj.png

Запрос отправили, получили кучку кода.
Теперь будем преобразовывать кучку кода в текстуру. Для этого воспользуемся клиентской функцией dxCreateTexture (https://wiki.multitheftauto.com/wiki/DxCreateTexture)
Вернёмся снова к клиентскому файлу. В конец добавим данные строчки:

function setImage(texture)
image = dxCreateTexture(texture) --Создаём текстуру из кода, который будет отправлен в триггере
end
Данный код создаст из текстуры полноценное изображение.
Но ведь мы ещё не приняли триггер?
Давайте же его примем.
В любое место кода (за исключением функций и событий) добавляем данный код:

addEvent("sendImageToClient", true) --Принимаем загрузку триггера "sendImageToClient", true в качестве Shared Event
addEventHandler("sendImageToClient", getRootElement(), setImage) --Добавляем событие "sendImageToClient", и присваиваем ему функцию установки текстуры
Сохраняем в этом же файле.
http://i.imgur.com/xQKi4QC.png

Вот теперь у нас есть возможность загружать изображение по URL. Но это фактически. На сервере мы ещё не можем вызвать функцию так как у нас нечем её вызывать, и мы ещё не загрузили скрипты в Meta.XML.
Давайте создадим команду, с помощью которой мы будем загружать URL на изображение, а так-же команду для очищения (чтобы не мешалась на экране).
Снова перейдём в клиентский файл, и в любое место кода (кроме функции и событий) добавим данный код:

addCommandHandler("clearimage", --Создаём команду clearimage
function()
image = 0 --Обнуляем изображение
end)

Так как команда без дополнительных значений, мы можем обойтись в функции и без аргументов.
Сохраняем в этом же файле.
http://i.imgur.com/VrzTZwY.png

Теперь у нас есть команда для очищения изображения. Но как же загрузка?
Давайте добавим команду загрузки изображения по URL.
Для этого перейдём в серверный файл, и в любое место кода (кроме функций и событий) добавим следующий код:

addCommandHandler("setimage", --Создаём команду setimage
function(source, _, url) --Даём ей возможность загрузки URL. Обычно первые 2 аргумента на серверной стороне, это игрок и команда, но так как команда нам не важна (так как она уже задана), мы просто ввели символ "_". url - аргумент для ввода команды. Теперь команда выглядит так: "setimage url"
loadImageByURL(url, source) --Вызываем функцию по загрузке изображения для игрока source по ссылке url
end)

Сохраняем в этом же серверном файле.
http://i.imgur.com/XfDbuDh.png

Отлично. Теперь мы могли бы вводить URL для изображения, воспользовавшись командой "setimage URL-НА-ИЗОБРАЖЕНИЕ" (кстати, лучше всего вводить команды в консоль, не используя символ "/", так как в консоли присутствует возможность "Копировать/Вставить" как Ctrl+C/V) (Консоль вызывается клавишей ~ при английской раскладке, или F8 при любой). Но мы не можем вводить команды, потому что мы не загрузили скрипты.

Давайте же загрузим скрипты.
Для этого откроем файл meta.xml, и вспомним, как мы назвали клиентский и серверный файлы. Я воспользуюсь словом "CLIENT-NAME" и "SERVER-NAME" для того, чтобы вы могли вместо них вставить названия своих клиентского и серверного файлов (в кавычках).
Перед строчкой </meta> добавляем следующий код:

<script src="CLIENT-NAME.lua" type="client"/>
<script src="SERVER-NAME.lua" type="server"/>
src означаем то, где находится файл (пишется в кавычках, при использовании папки обозначается как "название-папки/файл.формат", без папки "файл.формат"), type - тип (бывает "client" и "server")
Сохраняем это в meta.xml.
http://i.imgur.com/dkqyNMe.png

Прекрасно. Мы создали ресурс по загрузке URL изображения на экран.
Но это ещё не всё. Функция fetchRemote требует прав администратора, следовательно нам надо их предоставить. Можно сделать это через ресурс admin, а лучше вручную.
Идём в директорию deathmatch, и видим файл acl.xml. Открываем его, и ищем:

<group name="Admin">
И примерно так-же, как и meta.xml вписываем в него:

<object name="resource.RESOURCENAME"></object>
Где после точки "resource." мы вписываем название нашего ресурса. У меня это "urlimg"

<object name="resource.urlimg"></object>
http://i.imgur.com/wTLvdRg.png

И теперь мы можем запускать сервер.
http://i.imgur.com/WCe3Wpb.jpg

Спасибо за внимание.

L0ndl3m
28.08.2014, 14:14
Лайк исключительно за TDG.

Шучу конечно, отличный урок.