Web Updater

* Forbade interactions outside the Updater screen
* Added Automatic Updates preference
* Updated config vars
* Disabled custom GC values for wider testing purposes
* Added update logo fallback in case of unexpected circumstances
* Added CheckUpdates Screen Action Function
* Simplified parts of the updater code and reduced bloat
This commit is contained in:
LoafyLemon 2022-06-13 00:04:59 +01:00
parent 1453df5627
commit 6fa1e0a0fa
7 changed files with 170 additions and 147 deletions

View File

@ -171,7 +171,7 @@ screen game_menu(title, scroll=None, yinitial=0.0):
label title anchor (0.5, 0.5) align (0.86, 0.15) label title anchor (0.5, 0.5) align (0.86, 0.15)
if main_menu: if main_menu and not title == "Updater":
key "game_menu" action ShowMenu("main_menu") key "game_menu" action ShowMenu("main_menu")
style game_menu_outer_frame is empty: style game_menu_outer_frame is empty:
@ -220,6 +220,7 @@ screen navigation(title=None):
default show_quick_start = False default show_quick_start = False
default show_dev_start = False default show_dev_start = False
default is_sensitive = not bool(title == "Updater")
key "keydown_K_LSHIFT" action SetLocalVariable("show_quick_start", True) key "keydown_K_LSHIFT" action SetLocalVariable("show_quick_start", True)
key "keyup_K_LSHIFT" action SetLocalVariable("show_quick_start", False) key "keyup_K_LSHIFT" action SetLocalVariable("show_quick_start", False)
@ -243,37 +244,38 @@ screen navigation(title=None):
if main_menu: if main_menu:
if not title: if not title:
if (updater.can_update() or config.developer) and getattr(store, "UPDATE_URL", None):
if new_version: if not renpy.mobile:
textbutton "Update available" action install_updates() style_prefix "update_available" if UPDATE_VER:
textbutton "Install updates" action InstallUpdates() style_prefix "update_available"
else: else:
textbutton "Check for updates" action Function(check_updates, 300) textbutton "Check for updates" action CheckUpdates(300)
if show_quick_start: if show_quick_start:
textbutton _("Quick Start") action Start("start_quick") textbutton _("Quick Start") action Start("start_quick") sensitive is_sensitive
elif show_dev_start: elif show_dev_start:
textbutton _("Developer Start") action Start("start_dev") textbutton _("Developer Start") action Start("start_dev") sensitive is_sensitive
else: else:
textbutton _("Start") action Start() textbutton _("Start") action Start() sensitive is_sensitive
else: else:
textbutton _("Return") action Return() textbutton _("Return") action Return() sensitive is_sensitive
else: else:
textbutton _("Return") action Return() textbutton _("Return") action Return() sensitive is_sensitive
textbutton _("History") action ShowMenu("history") textbutton _("History") action ShowMenu("history") sensitive is_sensitive
textbutton _("Save") action ShowMenu("save") textbutton _("Save") action ShowMenu("save") sensitive is_sensitive
textbutton _("Load") action ShowMenu("load") textbutton _("Load") action ShowMenu("load") sensitive is_sensitive
textbutton _("Preferences") action ShowMenu("preferences") textbutton _("Preferences") action ShowMenu("preferences") sensitive is_sensitive
if main_menu: if main_menu:
textbutton _("Mods") sensitive bool(mods_list) action ShowMenu("mods") textbutton _("Mods") sensitive (bool(mods_list) and is_sensitive) action ShowMenu("mods")
textbutton _("Credits") action Jump("credits") textbutton _("Credits") action Jump("credits") sensitive is_sensitive
if not renpy.mobile: if not renpy.mobile:
textbutton _("Quit") action Quit(confirm=not main_menu) textbutton _("Quit") action Quit(confirm=not main_menu) sensitive is_sensitive
else: else:
textbutton _("Help") action ShowMenu("help") textbutton _("Help") action ShowMenu("help") sensitive is_sensitive
textbutton _("Main Menu") action MainMenu() textbutton _("Quit to menu") action MainMenu() sensitive is_sensitive
style navigation_vbox: style navigation_vbox:
xsize 250 xsize 250

View File

@ -62,6 +62,7 @@ screen preferences_general():
if not renpy.mobile: if not renpy.mobile:
textbutton _("Tooltips") action settings.Toggle("tooltip") textbutton _("Tooltips") action settings.Toggle("tooltip")
textbutton _("System Cursor") action Preference("system cursor", "toggle") textbutton _("System Cursor") action Preference("system cursor", "toggle")
textbutton _("Automatic Updates") action settings.Toggle("updates")
default trans = config.intra_transition default trans = config.intra_transition

View File

@ -22,6 +22,7 @@ init python:
settings.default("tutorials", True) settings.default("tutorials", True)
settings.default("preserve_aspect_ratio", True) settings.default("preserve_aspect_ratio", True)
settings.default("animations", True) settings.default("animations", True)
settings.default("updates", True)
# Configuration # Configuration
# https://www.renpy.org/doc/html/config.html # https://www.renpy.org/doc/html/config.html
@ -35,10 +36,10 @@ define config.console = True
# Game version and naming # Game version and naming
define config.version = "1.43.0" define config.version = "1.43.0"
define compatible_version = 1.43 define compatible_version = 1.43
define config.name = "WT Silver" define config.name = "Witch Trainer Silver"
# Application window settings # Application window settings
define config.window_title = "Witch Trainer: Silver (v{}) ({}) ({}-bit)".format(config.version, get_renderer(), renpy.bits) define config.window_title = "{} (v{}) ({}) ({}-bit)".format(config.name, config.version, get_renderer(), renpy.bits)
define config.window_icon = "gui/icon.webp" define config.window_icon = "gui/icon.webp"
define config.screen_width = 1080 define config.screen_width = 1080
define config.screen_height = 600 define config.screen_height = 600
@ -89,7 +90,7 @@ init -1:
define config.late_images_scan = True define config.late_images_scan = True
# Saving and loading # Saving and loading
define config.save_directory = "WTS" define config.save_directory = "Witch Trainer Silver"
define config.has_autosave = True define config.has_autosave = True
define config.autosave_on_quit = True define config.autosave_on_quit = True
define config.autosave_on_choice = True define config.autosave_on_choice = True
@ -123,10 +124,10 @@ define config.exit_replay_transition = None
define config.say_attribute_transition = d3 define config.say_attribute_transition = d3
# Garbage Collector # Garbage Collector
define config.manage_gc = True # define config.manage_gc = True
define config.gc_thresholds = (25000, 10, 10) # define config.gc_thresholds = (25000, 10, 10)
define config.idle_gc_count = 10000 # define config.idle_gc_count = 10000
define config.gc_print_unreachable = False # define config.gc_print_unreachable = False
################################################ ################################################
## Build configuration ## ## Build configuration ##
@ -140,33 +141,20 @@ init python:
build.include_old_themes = False build.include_old_themes = False
build.exclude_empty_directories = True build.exclude_empty_directories = True
build.archive("scripts", "all") build.classify("**.rpy", "renpy")
build.archive("characters", "all") build.classify("**.rpyc", "all")
build.archive("images", "all") build.classify("game/images.whitespace", "all")
build.archive("sounds", "all") build.classify("**.webp", "all")
build.archive("music", "all") build.classify("**.webm", "all")
build.archive("gui", "all") build.classify("**.ogg", "all")
build.archive("old", "all")
build.classify("game/scripts/**.rpy", "scripts") build.classify("game/gui/**", "all")
build.classify("game/scripts/**.rpyc", "scripts") build.classify("android-icon_*.png", "android")
build.classify("old-game/scripts/**.rpy", "old") build.classify("android-presplash.jpg", "android")
build.classify("old-game/scripts/**.rpyc", "old") build.classify("icon.icns", "mac")
build.classify("game/images.whitespace", "scripts") build.classify("icon.ico", "windows")
build.classify("game/characters/**.webp", "characters") build.classify("game/presplash_*.png", "renpy")
build.classify("game/images/**.webp", "images") build.classify("game/outfits/**", "all")
build.classify("game/images/**.webm", "images")
build.classify("game/sounds/**.ogg", "sounds")
build.classify("game/music/**.ogg", "music")
build.classify("game/gui/**", "gui")
build.classify("game/interface/**.webp", "gui")
build.classify("android-icon_*.png", "android gui")
build.classify("android-presplash.jpg", "android gui")
build.classify("icon.icns", "mac gui")
build.classify("icon.ico", "windows gui")
build.classify("game/presplash_*.png", "mac windows linux gui")
build.classify("game/outfits/**", "mac windows linux")
build.classify("**.py", None) build.classify("**.py", None)
build.classify("**.txt", None) build.classify("**.txt", None)

View File

@ -1,54 +0,0 @@
# This file can be safely deleted to permanently disable update checks.
init python:
import requests
import binascii
UPDATE_URL = ""
LOGO_URL = ""
new_version = None
def check_updates(interval=3600*6):
if not UPDATE_URL:
return
global new_version
new_version = updater.UpdateVersion(binascii.unhexlify(UPDATE_URL), check_interval=interval)
def install_updates():
if not UPDATE_URL:
return None
return updater.Update(binascii.unhexlify(UPDATE_URL), patch=True)
def fetch_update_logo(url):
if not (updater.can_update() or config.developer) or new_version is None or not LOGO_URL:
return Null()
filename = "logo_{}.png".format(new_version)
path = os.path.join(config.basedir, "updates/{}".format(filename))
# Read file if exists
if os.path.isfile(path):
with open(path, "rb") as f:
data = f.read()
return im.Data(data, path)
# Fetch file if doesn't exist
try:
url = binascii.unhexlify(url)
response = requests.get(url, timeout=5)
data = response.content
except:
return Null()
if not data:
return Null()
with open(path, "wb") as f:
f.write(data)
return im.Data(data, path)
check_updates()

File diff suppressed because it is too large Load Diff

View File

@ -2,3 +2,4 @@
* *
# Except this file # Except this file
!.gitignore !.gitignore
!generic.webp

BIN
update/generic.webp (Stored with Git LFS) Normal file

Binary file not shown.