HTTPS/HTTP更新器 link

Ren’Py包含一個更新器(updater),可以從Ren’Py項目所在的web伺服器上自動下載和安裝更新。 更新器只能在Windows和Linux平台運行,不支持macOS、安卓和iOS。

Ren’Py更新器自動實施下列步驟:

  1. 下載控制更新內容的索引文件。

  2. 詢問用戶是否需要執行更新。

  3. 生成一個當前磁碟文件的歸檔。

  4. 從伺服器下載一個zsync控制文件。

  5. 使用zsync工具將歸檔文件更新到伺服器版本。zsync會自動計算兩份歸檔文件的差別,並嘗試下載有差別的部分。

  6. 歸檔文件解包,並替換原來磁碟上的文件。

  7. 刪除新版本中已經移除的舊版本文件。

  8. 重啟遊戲。

Ren’Py更新器在處理過程會顯示一個更新界面,提示用戶處理並允許用戶退出更新。

目前有兩種更新檔案格式。最新的格式為 rpu ,在Ren’Py 8.2中引入。 更早的版本格式為zsync,已經標記為過期(obsolete),可以在更早的Ren’Py版本中使用。

伺服器要求 link

更新器要求創作者有自己的服務主機。用戶需要可以通過URL直接下載升級文件,所以創作者的伺服器必須支持HTTP請求。

https不能用於補丁升級,但可以用於全量更新。

(這意味著需要為伺服器付費。共享文件類型的網站並不支持這種更新。)

如果 patch 參數設置為False,或者指定了https的url連結, 更新器不會嘗試給遊戲打補丁,而是下載完整歸檔文件,解包並更新。 由於完整歸檔一般都比較大,需要更多Web伺服器提供下載。

生成更新 link

生成分發版時會自動生成更新。 構建更新器前,將 options.rpy 文件中的 build.include_update 設置為True。 這樣能解鎖啟動器(launcher)中“生成分發版”的“生成更新”選項。勾選這項後,Ren’Py就可以生成更新文件了。

更新文件包含下列內容:

updates.json

可用更新和版本號的索引。

updates.ecdsa

updates.json文件簽名,用於驗證是否已經在本地快取。

創作者必須把所有這些文件都上傳到web伺服器的同一目錄下。

函數 link

要觸發更新時,需要調用updater.update函數或updater.Update行為(action)。

updater.Update(*args, **kwargs) link

這個行為調用 updater.update() 函數。所有入參會儲存並傳入那個函數。

updater.UpdateVersion(url, check_interval=21600, simulate=None, **kwargs) link

這個函數會連接 url 的伺服器,並判斷是否有可用的新版本。如果有可用更新就返回新版本號,否則返回None。

由於連接伺服器需要消耗一些時間,這個函數在後台啟動一個執行緒,連接伺服器成功後立刻返回版本號,如果連不上伺服器則返回None。 後台執行緒一旦連線到伺服器會重啟當前交互行為,會讓調用更新函數的界面更新。

對應每個連接的url都需要分配至少1個Ren’Py會話(session),並在每個 check_interval 秒的週期內保持會話。如果不能連接伺服器,就返回快取數據。

額外的關鍵字入參(包括 simulate )會如同傳給 updater.update() 一樣,傳給更新機制使用。

updater.can_update(base=None) link

如果可以更新成功則返回True。如果無法完全更新(比如update目錄被刪除了),就返回False。

注意這個函數並不實際進行更新操作。實際更新需要使用函數 updater.UpdateVersion()

updater.get_installed_packages(base=None) link

返回已安裝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') link

將這個Ren’Py遊戲更新到最新版。

url

update.json文件的URL地址。

base

更新的基目錄。預設為當前遊戲的基目錄。(這項通常會忽略。)

force

就算版本號相同也強制更新。(用於測試。)

public_key

檢查更新簽名的公鑰PEM文件路徑。(這項通常會忽略。)

simulate

這項用於測試GUI,而不是真的實行更新。這項可能的值為:

  • None表示實行更新。

  • “available”表示有可用更新時進行測試。

  • “not_available”表示無可用更新時進行測試。

  • “error”表示測試更新報錯。

add

本次更新添加的包(package)列表。DLC必須要有這個列表。

restart

更新後重啟遊戲。

confirm

Ren’Py是否提示用戶確認此次升級。若為False,此次升級將不需要用戶確認。

patch

若為True,Ren’Py會以補丁形式更新遊戲,只下載變更的數據。 若為False,Ren’Py會全量更新遊戲,下載整個遊戲。 更新url不以“http”開頭時,該項自動設置為False.

prefer_rpu

若為True,當兩種更新格式都存在時,Ren’Py優先使用RPU格式更新。

allow_empty

若為True,Ren’Py可以在根目錄沒有任何更新資訊的情況下執行更新。(需要使用 add 設置更新目錄。)

done_pause

若為True,更新下載完成後遊戲會暫停。 若為False,遊戲會立刻執行更新(重啟或退出)。

allow_cancel

若為True,用戶可以主動取消更新。 若為False,用戶無法取消更新。

screen

更新時顯示的界面名。

界面 link

如果要訂製更新器(updater)的外觀,創作者可以重寫 update 界面。默認界面定義在common/00updater.rpy中。

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

更新界面可以有一個入參,即一個Update類對象,參數名必須為 u。 Update對象包含下列欄位,可用於界面訂製化:

class update.Updater link
state link

更新器當前狀態。各種可能的狀態值和含義可參考上列的界面定義。這些狀態值是Updater對象中的常量。

message link

若不是None,該項是向用戶顯示的資訊。

progress link

若不是None,表示當前操作進度,一個介於0.0和1.0之間的浮點數。

can_proceed link

若為True,會彈出一個帶按鈕的界面,提供用戶點擊並更新。

proceed link

若 can_proceed 為True,該項是一個行為(action)。當用戶點擊“執行”按鈕後將調用該行為。

can_cancel link

若為True,會彈出一個帶按鈕的界面,允許用戶點擊並取消更新。

cancel link

若 can_cancel 為True,該項是一個行為(action)。當用戶點擊“取消”按鈕後將調用該行為。

old_disk_total link

若不是None,這是一個整數,表示更新前遊戲占用儲存空間的字長(Byte)數。

new_disk_total link

若不是None,這是一個整數,表示更新後遊戲占用儲存空間的字長(Byte)數。

download_total link

若不是None,這是一個整數,表示待更新下載數據的總字長(Byte)數。

download_done link

若不是None,這是一個整數,表示更新中已下載數據的總字長(Byte)數。

write_total link

若不是None,這是一個整數,表示更新後將寫入儲存數據的字長(Byte)數。

write_done link

若不是None,這是一個整數,表示更新中已寫入儲存數據的字長(Byte)數。