HTTPS/HTTP 업데이터

Ren'Py에는 웹 호스트에서 Ren'Py 게임의 업데이트를 자동으로 다운로드하고 설치하는 업데이터가 포함되어 있습니다. 업데이트는 macOS 앱을 제외한 데스크톱 플랫폼에서 작동합니다.

이 과정에서 Ren'Py 업데이터는 업데이터 스크린을 표시하여 사용자에게 진행 여부를 묻고, 필요한 경우 취소할 수 있도록 합니다.

두 가지 업데이트 형식을 지원합니다. 최신 형식은 rpu이며 Ren'Py 8.2에서 도입되었습니다. 이전 형식인 zsync는 더 이상 권장되지 않지만, 구버전에서 업데이트할 수 있도록 생성할 수 있습니다.

서버 요구 사항

업데이터를 사용하려면 직접 호스팅을 마련해야 합니다. 해당 URL에 직접 접속하여 업데이트 파일을 다운로드할 수 있어야 하며, 서버가 HTTP 범위 요청을 지원해야 합니다.

업데이트 빌드

업데이트는 배포판을 빌드할 때 자동으로 빌드됩니다. 업데이트를 빌드하려면 options.rpy에서 build.include_update를 True로 설정하세요. 그러면 런처의 “배포판 빌드(Build Distributions)”에 “업데이트 빌드(Build Updates)” 옵션이 활성화됩니다. 이 옵션을 선택하면 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의 서버에 접속하여 해당 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

updates.json 파일의 URL입니다.

base

업데이트할 기본 디렉터리입니다. 기본값은 현재 게임의 기본 디렉터리입니다. (일반적으로 지정하지 않아도 됩니다.)

force

버전 번호가 같아도 강제로 업데이트합니다. (테스트에 사용합니다.)

public_key

업데이트 서명을 검증할 공개 키가 들어 있는 PEM 파일의 경로입니다. (일반적으로 지정하지 않아도 됩니다.)

simulate

실제로 업데이트하지 않고 업데이트 GUI를 테스트할 때 사용합니다. 다음 값을 사용할 수 있습니다.

  • None이면 업데이트를 수행합니다.

  • "available"이면 업데이트가 있는 경우를 테스트합니다.

  • "not_available"이면 업데이트가 없는 경우를 테스트합니다.

  • "error"이면 업데이트 오류를 테스트합니다.

add

이번 업데이트에서 추가할 패키지 목록입니다. DLC에만 필요합니다.

restart

true이면 업데이트가 끝났을 때 게임을 다시 실행합니다. "utter"이면 대신 renpy.utter_restart()를 호출합니다. False이면 업데이트만 종료합니다.

confirm

사용자에게 업데이트 확인을 요청할지 지정합니다. False이면 확인 없이 업데이트를 진행합니다.

patch

true이면 변경된 데이터만 다운로드하여 게임에 패치를 적용하려고 시도합니다. false이면 게임 전체를 다운로드한 뒤 그 데이터로 업데이트합니다. URL이 "http:"로 시작하지 않으면 자동으로 false로 설정됩니다.

RPU 업데이트 형식을 사용하면 무시됩니다.

prefer_rpu

True이고 zsync와 RPU를 모두 사용할 수 있으면 업데이트에 RPU 형식을 우선 사용합니다.

allow_empty

True이면 기본 디렉터리에 업데이트 정보가 없어도 업데이트를 진행할 수 있습니다. (이 경우 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 _("업데이트 프로그램")

      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일 때 사용자가 취소 버튼을 누르면 실행해야 하는 액션입니다.

old_disk_total

None이 아니면 업데이트 시작 시 게임이 디스크에서 차지하던 총 바이트 수를 나타내는 정수입니다.

new_disk_total

None이 아니면 업데이트 종료 시 게임이 디스크에서 차지할 총 바이트 수를 나타내는 정수입니다.

download_total

None이 아니면 업데이트 중 다운로드할 총 바이트 수를 나타내는 정수입니다.

download_done

None이 아니면 업데이트 중 지금까지 다운로드한 바이트 수를 나타내는 정수입니다.

write_total

None이 아니면 업데이트 중 디스크에 기록할 총 바이트 수를 나타내는 정수입니다.

write_done

None이 아니면 업데이트 중 지금까지 디스크에 기록한 바이트 수를 나타내는 정수입니다.