HTTPS/HTTP Updater
В Ren'Py встроено средство обновления (updater), которое может автоматически загружать и устанавливать обновления для игры Ren'Py с веб-хоста. Обновления работают на десктопных платформах, за исключением приложений для macOS.
Во время этого процесса средство обновления Ren'Py показывает экран обновления, предлагая пользователю продолжить и позволяя отменить операцию при необходимости.
Поддерживаются два формата обновлений. Современный формат называется rpu и был представлен в Ren'Py 8.2. Старый формат, называемый zsync, устарел, но может быть сгенерирован для обновления со старых версий.
Требования к серверу
Средство обновления требует, чтобы вы предоставили свой собственный хостинг. Вы должны иметь возможность загружать файлы обновлений, переходя по соответствующему URL напрямую, и ваш сервер должен поддерживать HTTP range queries (запросы диапазонов).
Сборка обновления
Обновления создаются автоматически при сборке дистрибутивов. Чтобы собрать
обновление, установите build.include_update в True в options.rpy. Это
разблокирует опцию "Build Updates" в разделе "Build Distributions"
лаунчера. Отметьте эту опцию, и Ren'Py создаст файлы обновления.
Файлы обновления состоят из:
- updates.json
Индекс доступных обновлений и их версий.
- updates.ecdsa
Подпись файла updates.json, используемая для проверки того, что он не был изменён.
- rpu/
Каталог rpu содержит метаданные и данные, используемые для обновлений.
Вы должны загрузить их в одно и то же место на вашем веб-сервере.
Функции
Чтобы запустить обновление, вызовите либо updater.update, либо действие updater.Update.
- updater.Update(*args, **kwargs)
Действие, которое вызывает
updater.update(). Все аргументы сохраняются и передаются в эту функцию.
- updater.UpdateVersion(url, check_interval=21600, simulate=None, **kwargs)
Эта функция связывается с сервером по адресу url и определяет, доступна ли по этому адресу более новая версия программного обеспечения. Если да, функция возвращает новую версию. В противном случае она возвращает None.
Поскольку обращение к серверу может занять некоторое время, эта функция запускает фоновый поток и немедленно возвращает версию, полученную при последнем обращении к серверу, или None, если обращений к серверу не было. Фоновый поток перезапустит текущее взаимодействие после установления связи с сервером, что приведёт к обновлению экранов, вызывающих эту функцию.
Обращение к каждому url происходит не более одного раза за сессию Ren'Py и не чаще, чем каждые check_interval секунд. Когда обращение к серверу не выполняется, возвращаются кэшированные данные.
Дополнительные именованные аргументы (включая simulate) передаются в механизм обновления, как если бы они были переданы в
updater.update().
- updater.can_update(base=None)
Возвращает true, если обновление может быть успешно выполнено. Возвращает false, если обновление совершенно невозможно (например, если папка с обновлениями была удалена).
Обратите внимание, что эта функция не определяет, доступно ли обновление в действительности. Для этого используйте
updater.UpdateVersion().
- updater.get_installed_packages(base=None)
Возвращает список имён установленных DLC-пакетов.
- base
Базовая папка для обновления. По умолчанию используется базовая папка текущего проекта.
- updater.update(url, base=None, force=False, public_key=None, simulate=None, add=[], restart=True, confirm=True, patch=True, prefer_rpu=True, allow_empty=False, done_pause=True, allow_cancel=True, screen='updater')
Обновляет текущую игру Ren'Py до последней версии.
- url
URL к файлу updates.json.
- base
Базовая папка для обновления. По умолчанию — папка текущей игры. (Обычно этот параметр можно игнорировать.)
- force
Принудительно выполнить обновление, даже если номера версий совпадают. (Используется для тестирования.)
- public_key
Путь к PEM-файлу, содержащему публичный ключ, по которому проверяется подпись обновления. (Обычно этот параметр можно игнорировать.)
- simulate
Используется для тестирования интерфейсов обновления без фактического выполнения обновления. Может принимать значения:
None, чтобы выполнить обновление.
"available" для тестирования случая, когда обновление доступно.
"not_available" для тестирования случая, когда обновление недоступно.
"error" для тестирования ошибки обновления.
- add
Список пакетов для добавления во время этого обновления. Необходимо только для DLC.
- restart
Если true, игра будет перезапущена по завершении обновления. Если указано "utter", будет вызвана функция
renpy.utter_restart(). Если False, обновление просто завершится.- confirm
Должен ли Ren'Py запрашивать у пользователя подтверждение обновления? Если False, обновление продолжится без подтверждения.
- patch
Если true, Ren'Py попытается применить патч к игре, загружая только изменённые данные. Если false, Ren'Py загрузит полную копию игры и обновит её из этой копии. Этот параметр автоматически устанавливается в false, если url не начинается с "http:".
Игнорируется, если используется формат обновления RPU.
- prefer_rpu
Если True, Ren'Py будет предпочитать формат RPU для обновлений, если доступны и zsync, и RPU.
- allow_empty
Если True, Ren'Py разрешит обновление, даже если базовая папка не содержит информации для обновления. (В этом случае должен быть предоставлен параметр add).
- done_pause
Если true, игра приостановится после завершения обновления. Если false, она немедленно продолжит выполнение (перезапустится или вернётся).
- allow_cancel
Если true, пользователь сможет отменить обновление. Если false, пользователь не сможет отменить обновление.
- screen
Имя экрана для использования.
Экран
Чтобы настроить внешний вид средства обновления, вы можете переопределить экран updater.
Вот пример такого экрана:
screen updater(u=None):
add "#000"
frame:
style_group ""
has side "t c b":
spacing gui._scale(10)
label _("Updater")
fixed:
vbox:
if u.state == u.ERROR:
text _("Произошла ошибка:")
elif u.state == u.CHECKING:
text _("Проверка обновлений.")
elif u.state == u.UPDATE_NOT_AVAILABLE:
text _("Программа обновлена до последней версии.")
elif u.state == u.UPDATE_AVAILABLE:
text _("[u.version] доступна. Вы хотите её установить?")
elif u.state == u.PREPARING:
text _("Подготовка к загрузке обновлений.")
elif u.state == u.DOWNLOADING:
text _("Загрузка обновлений.")
elif u.state == u.UNPACKING:
text _("Распаковка обновлений.")
elif u.state == u.FINISHING:
text _("Завершение.")
elif u.state == u.DONE:
text _("Обновления установлены. Программа будет перезапущена.")
elif u.state == u.DONE_NO_RESTART:
text _("Обновления установлены.")
elif u.state == u.CANCELLED:
text _("Обновления были отменены.")
if u.message is not None:
null height gui._scale(10)
text "[u.message!q]"
if u.progress is not None:
null height gui._scale(10)
bar value (u.progress or 0.0) range 1.0 style "_bar"
hbox:
spacing gui._scale(25)
if u.can_proceed:
textbutton _("Продолжить") action u.proceed
if u.can_cancel:
textbutton _("Отмена") action u.cancel
Экрану обновления передаётся один параметр, объект Updater, который должен называться u. Объект Updater имеет следующие поля, которые можно использовать для настройки экрана:
- class updater.Updater
- state
Текущее состояние средства обновления. Возможные значения и их смысл смотрите в примере выше. Все значения являются константами объекта Updater.
- message
Если не None, сообщение для отображения пользователю.
- progress
Если не None, прогресс текущей операции в виде числа с плавающей запятой от 0.0 до 1.0.
- can_proceed
Если True, экран должен отобразить кнопку, которая позволит пользователю продолжить обновление.
- proceed
Если can_proceed имеет значение True, это действие, которое должно быть вызвано, когда пользователь нажимает кнопку продолжения.
- can_cancel
Если True, экран должен отобразить кнопку, которая позволит пользователю отменить обновление.
- cancel
Если can_cancel имеет значение True, это действие, которое должно быть вызвано, когда пользователь нажимает кнопку отмены.