Всем привет.
Заметил, что на форуме у многих ребят, которые что-то делают на Lua, возникают проблемы с написанием системы автообновления.
Автообновление - очень полезная штука в хороших руках, ведь ты можешь быстро фиксить мелкие проблемы и твоим пользователям не придётся искать апдейты вручную.
На самом деле ничего сложного в реализации автообновления для MoonLoader нет, даже не потребуются никакие левые библиотеки, кроме MoonLoader старше 019 и sampfuncs для вывода сообщений об обновлении в чат.
Недавно на форуме появилась
тема с гайдом по автообновлению, и, так как она основана на очень старой и несовершенной версии моей текущей системы (слизанной давным давно с Check Moonloader Updates), я решил создать эту тему, в которой вы найдетё надежный и проверенный временем способ обновлять ваши скрипты у пользователей автоматически.
Как это работает?
- После загрузки скрипта и запуска сампа первым делом скрипт проверяет, есть ли обновление на сервере. Он скачивает с сервера файл в формате JSON, в котором ты заранее указываешь текущую версию и ссылку, по которой эту версию можно скачать.
- Если текущая версия не совпадает с версией в JSON, скрипт автоматически пытается скачать новую, уведомляя об этом пользователя.
- Если url недоступен, пользователь увидит сообщение об этом в moonloader.log/консоли SF.
- Если новая версия не обнаружена, пользователь так же увидит сообщение в логе.
Серверная часть.
Первым делом тебе нужно позаботиться о сервере, с которого скрипт будет брать информацию о текущей версии и ссылку, по которой эту версию можно скачать. Нужно подумать, откуда скрипт будет скачивать твой JSON. Тебе нужно, чтобы json был доступен 24/7 и ты мог (и только ты!) его редактировать. Вариантов масса:
gitlab,
github,
jsonbin.io,
бесплатный хостинг (нажми справа на воздушный шар и получишь х2 к месту для файлов). Регистрируемся, создаем gist/файл и получаем на него прямую raw ссылку, а сам файл обновляем по мере необходимости.
Я много раз говорил про JSON, но так не объяснил что это такое. JSON — текстовый формат обмена данными, основанный на JavaScript. В updateurl указываем ссылку на .lua файл, а в latest - последнюю версию.
{
"updateurl": "http://www.qrlk.me/dev/moonloader/adblock/!adblock.lua",
"latest": "01.01.2019"
}
Кстати о версиях, вместо обычных 1.0 и 99.99.2, рекомендую использовать дату выхода версии: так проще понять когда было обновление и это вполне допустимо для штук размером с 1 файл, но тут уже кто как хочет.
Этот json потом преобразуется в таблицу через
decodeJson().
Интеграция в скрипт.
Засовываем это в main(), перед while. Нужно вызвать функцию один раз, когда самп уже загрузился. Заменяем json_url и url на свои:
- json_url - прямая ссылка на ваш json.
- prefix - префикс перед сообщениями об обновлении.
- url - при недоступности json_url, пользователь в логе увидит сообщение с необходимостью проверить обнову вручную на url. Это может быть ваш сайт или тема на форуме.
autoupdate("тут ссылка на ваш json", '['..string.upper(thisScript().name)..']: ', "тут ссылка на ваш сайт/url вашего скрипта на форуме (если нет, оставьте как в json)")
Засовываем вниз скрипта, сохранять копирайт автора или нет - дело вашей совести.
--
-- _ _ _ _____ ___ _ _ ____ ____ _ _____ _____ ______ __ ___ ____ _ _ __
-- / \ | | | |_ _/ _ \| | | | _ \| _ \ / \|_ _| ____| | __ ) \ / / / _ \| _ \| | | |/ /
-- / _ \| | | | | || | | | | | | |_) | | | |/ _ \ | | | _| | _ \\ V / | | | | |_) | | | ' /
-- / ___ \ |_| | | || |_| | |_| | __/| |_| / ___ \| | | |___ | |_) || | | |_| | _ <| |___| . \
-- /_/ \_\___/ |_| \___/ \___/|_| |____/_/ \_\_| |_____| |____/ |_| \__\_\_| \_\_____|_|\_\
--
-- Author: http://qrlk.me/samp
--
function autoupdate(json_url, prefix, url)
local dlstatus = require('moonloader').download_status
local json = getWorkingDirectory() .. '\\'..thisScript().name..'-version.json'
if doesFileExist(json) then os.remove(json) end
downloadUrlToFile(json_url, json,
function(id, status, p1, p2)
if status == dlstatus.STATUSEX_ENDDOWNLOAD then
if doesFileExist(json) then
local f = io.open(json, 'r')
if f then
local info = decodeJson(f:read('*a'))
updatelink = info.updateurl
updateversion = info.latest
f:close()
os.remove(json)
if updateversion ~= thisScript().version then
lua_thread.create(function(prefix)
local dlstatus = require('moonloader').download_status
local color = -1
sampAddChatMessage((prefix..'Обнаружено обновление. Пытаюсь обновиться c '..thisScript().version..' на '..updateversion), color)
wait(250)
downloadUrlToFile(updatelink, thisScript().path,
function(id3, status1, p13, p23)
if status1 == dlstatus.STATUS_DOWNLOADINGDATA then
print(string.format('Загружено %d из %d.', p13, p23))
elseif status1 == dlstatus.STATUS_ENDDOWNLOADDATA then
print('Загрузка обновления завершена.')
sampAddChatMessage((prefix..'Обновление завершено!'), color)
goupdatestatus = true
lua_thread.create(function() wait(500) thisScript():reload() end)
end
if status1 == dlstatus.STATUSEX_ENDDOWNLOAD then
if goupdatestatus == nil then
sampAddChatMessage((prefix..'Обновление прошло неудачно. Запускаю устаревшую версию..'), color)
update = false
end
end
end
)
end, prefix
)
else
update = false
print('v'..thisScript().version..': Обновление не требуется.')
end
end
else
print('v'..thisScript().version..': Не могу проверить обновление. Смиритесь или проверьте самостоятельно на '..url)
update = false
end
end
end
)
while update ~= false do wait(100) end
end
Что дальше?
В принципе, базовое автообновление у вас уже есть. Можно доработать эту систему так, как вам хочется.
Например, можно спрашивать подтверждения пользователя, хочет ли он обновится, а ещё показывать ему краткую информацию о том, что ты сделал для него в новом обновлении.
В моих же скриптах используется усовершенственная версия этой системы, где пользователь получает json в обмен на статистику использования: сервер, id диска, ник, версия муна, версия скрипта, путь к гта, а так же может
посмотреть changelog, открыв ссылку прямо из игры. Для первого нужен сервер, базовые знания php и mysql.
Пример реализации