Исходник Гайд Lua || Как сделать нормальное автообновление вашего скрипта?

The Spark

Известный
656
688
лучше используй дропбокс
Не используете DropBox!!!
upload_2019-6-10_10-38-54.png
 

Oreshka23

Известный
341
165
Чё показавать то? Мой дропбокс заблокировали за большой трафик по это ссылке. Просто говорю, что если вы делаете проект с авто-обновлением, никогда не юзайте DropBox!
Ну кто знает, может быть ты с дропбокса каждую секунду что-то качал, аккаунт блокируют при большом трафике, не помню сколько именно или сто тысяч скачиваний
 

Foxy1e3t

Известный
45
62
Дичайшим образом извиняюсь, но как прикажете обновлять .luac?
 

Mr_Incognito

Активный
331
51
Спасибо! Всё получилось, правда только на хостинге, на гитхабе и гитлабе кодировка ломается какого то хрена, так и не понял что надо делать.
Всем привет.

Заметил, что на форуме у многих ребят, которые что-то делают на 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. Это может быть ваш сайт или тема на форуме.
Lua:
autoupdate("тут ссылка на ваш json", '['..string.upper(thisScript().name)..']: ', "тут ссылка на ваш сайт/url вашего скрипта на форуме (если нет, оставьте как в json)")
Засовываем вниз скрипта, сохранять копирайт автора или нет - дело вашей совести.
Lua:
--
--     _   _   _ _____ ___  _   _ ____  ____    _  _____ _____   ______   __   ___  ____  _     _  __
--    / \ | | | |_   _/ _ \| | | |  _ \|  _ \  / \|_   _| ____| | __ ) \ / /  / _ \|  _ \| |   | |/ /
--   / _ \| | | | | || | | | | | | |_) | | | |/ _ \ | | |  _|   |  _ \\ 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.
Пример реализации

Подскажите пожалуйста, а если мне надо обновить 2 файла? Как сделать так, чтоб при обновлении он скачал луа и ини файл? Если можно, ткните носом где что дописать, а то я даун.
 
Последнее редактирование:

ImPasha

Software Developer & System Administrator
Друг
1,789
2,141
Подскажите пожалуйста, а если мне надо обновить 2 файла? Как сделать так, чтоб при обновлении он скачал луа и ини файл? Если можно, ткните носом где что дописать, а то я даун.
Ну можно архивировать нужные файлы в ZIP-архив, потом скачивать его и распаковывать.
 
  • Нравится
Реакции: AnWu

JLCUHA

Участник
28
7
Постоянно такое сообщение - [ML] (script) Daniels Helper: v2.0:
Не могу проверить обновление. Смиритесь или проверьте самостоятельно на
В чём может быть проблема?
 

ImPasha

Software Developer & System Administrator
Друг
1,789
2,141
Постоянно такое сообщение - [ML] (script) Daniels Helper: v2.0:
Не могу проверить обновление. Смиритесь или проверьте самостоятельно на
В чём может быть проблема?
Сказали же, хватит использовать DB для загрузки оттуда обновлений.
Используйте GitHub или GitLab, ну либо хостинг за 100 рублей возьмите. В чём проблема?
 

Tema05

Известный
1,471
435
Пробовал много сайтов и дропбокс самый удобный для этих целей. Легко добавить, удалить, заменить файл, обновление ссылок очень быстрое.(в конце нужно заменить 0 на 1 чтоб ссылки работали). Отличный пример, изучил и сам написал код как мне надо.
Я посчитал что-бы превысить бесплатный лимит в 20ГБ (у меня скрипт 4к строк и ещё файлов 12 библиотек) нужно скачать все файлы 5400+ раз
 
Последнее редактирование:

Licht

Известный
238
32
Для Moonloader 0.27, сменить строку где decodeJson на encodeJson
Update lua:
--
--     _   _   _ _____ ___  _   _ ____  ____    _  _____ _____   ______   __   ___  ____  _     _  __
--    / \ | | | |_   _/ _ \| | | |  _ \|  _ \  / \|_   _| ____| | __ ) \ / /  / _ \|  _ \| |   | |/ /
--   / _ \| | | | | || | | | | | | |_) | | | |/ _ \ | | |  _|   |  _ \\ 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 = encodeJson(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
 

Dr_lesbow

Потрачен
154
24
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
Что делать,если бесконченое автообновление скрипта?
 

Вложения

  • Daniels Helper.lua
    12.3 KB · Просмотры: 16