forked from SilverStudioGames/WTS
592 lines
25 KiB
Plaintext
592 lines
25 KiB
Plaintext
|
|
init python early:
|
|
import zipfile
|
|
import json
|
|
import os
|
|
import ctypes
|
|
import shutil
|
|
|
|
def is_admin():
|
|
try:
|
|
return bool(ctypes.windll.shell32.IsUserAnAdmin())
|
|
except:
|
|
return False
|
|
|
|
def ask_admin():
|
|
"""We only need admin privileges if we fail deleting a file."""
|
|
try:
|
|
ctypes.windll.shell32.ShellExecuteW(None, u"runas", unicode(sys.executable), unicode(" ".join(sys.argv)), None, 1)
|
|
return True
|
|
except:
|
|
return False
|
|
|
|
def remove_file(f):
|
|
f = os.path.join(config.basedir, f)
|
|
|
|
if not os.path.isfile(f):
|
|
return 0
|
|
|
|
try:
|
|
os.remove(f)
|
|
except OSError as e:
|
|
print "Cannot delete '{}'".format(f)
|
|
print "Error: {}".format(e)
|
|
return 2
|
|
else:
|
|
print "'{}' deleted".format(f)
|
|
return 1
|
|
|
|
def copytree(src, dst, symlinks=False, ignore=None):
|
|
for item in os.listdir(src):
|
|
s = os.path.join(src, item)
|
|
d = os.path.join(dst, item)
|
|
if os.path.isdir(s):
|
|
shutil.copytree(s, d, symlinks, ignore)
|
|
else:
|
|
shutil.copy2(s, d)
|
|
|
|
def version_float():
|
|
control, major, minor = config.version.split(" ")[0].split(".")
|
|
return float("{}.{}{}".format(control, major, minor))
|
|
|
|
# This function is no longer being used to check for potential updates.
|
|
|
|
# def version_check():
|
|
# if config.developer:
|
|
# return False
|
|
|
|
# import urllib2
|
|
|
|
# request = urllib2.Request(binascii.unhexlify("68747470733a2f2f706173746562696e2e636f6d2f7261772f424e354261647639"))
|
|
|
|
# try:
|
|
# response = urllib2.urlopen(request)
|
|
# except URLError as e:
|
|
# if hasattr(e, "reason"):
|
|
# print "Cannot check for updates. Server cannot be reached."
|
|
# print "Reason: {}".format(e.reason)
|
|
# elif hasattr(e, "code"):
|
|
# print "Cannot check for updates. Server cannot fulfill the request."
|
|
# print "Error: {}".format(e.code)
|
|
# return False
|
|
|
|
# current = version_float()
|
|
# latest = response.read()
|
|
|
|
# return current >= float(latest)
|
|
|
|
def version_patch():
|
|
if renpy.is_init_phase():
|
|
# Don't update save files from when game recovers from a crash.
|
|
return
|
|
|
|
latest = version_float()
|
|
|
|
if not hasattr(renpy.store, "version"):
|
|
if hasattr(renpy.store, "save_internal_version"):
|
|
raise Exception("Loaded save file is incompatible. (Save Version: {}, Game Version: {})".format(getattr(renpy.store, "save_internal_version")), latest)
|
|
raise Exception("Loaded save file is incompatible. (Save Version: Unknown, Game Version: {})".format(latest))
|
|
|
|
current = version
|
|
|
|
if current > latest:
|
|
raise Exception("Loaded save file is incompatible. (Save Version: {}, Game Version: {})".format(current, latest))
|
|
|
|
if current < latest:
|
|
setattr(renpy.store, "version", latest)
|
|
message = "Have fun!"
|
|
|
|
achievements.attempt_repair()
|
|
|
|
if current < 1.401:
|
|
|
|
global inventory_mode, time_turner_ITEM, imagination, bdsm_imagination, cheat_reading, birthday_happened
|
|
|
|
inventory_mode=0
|
|
inventory.remove(time_turner_ITEM)
|
|
del time_turner_ITEM
|
|
del imagination
|
|
del bdsm_imagination
|
|
del cheat_reading
|
|
del birthday_happened
|
|
|
|
if renpy.get_screen("blkfade"):
|
|
renpy.hide_screen("blkfade")
|
|
|
|
if not ball_quest.E4_complete:
|
|
her_outfit_ball.price = 0
|
|
|
|
if current < 1.402:
|
|
|
|
global mr_ev_ADR, hg_pr_sex_skip
|
|
|
|
mirror.remove(mr_ev_ADR)
|
|
del mr_ev_ADR
|
|
ton_hat_classy.zorder=3
|
|
ton_hat_classy.set_layers()
|
|
tonks.rebuild()
|
|
del hg_pr_sex_skip
|
|
|
|
if renpy.music.get_playing(channel="bg_sounds") == "sounds/fire02.ogg":
|
|
renpy.music.stop(channel="bg_sounds")
|
|
|
|
if current < 1.41:
|
|
|
|
reset_variables("tutorial_dict")
|
|
|
|
cho_outfit_cheerleader.name = "Ravenclaw Cheerleader Uniform"
|
|
cho_outfit_party.name = "Clubslut Outfit"
|
|
cho_outfit_bikini.name = "Micro Bikini Set"
|
|
her_outfit_bikini2.name = "Leathered Bikini Set"
|
|
her_outfit_bikini3.name = "Sling Bikini Set"
|
|
her_outfit_witch.name = "16th Century Witch Costume"
|
|
her_outfit_slutty_schoolgirl.name = "Slutty Schoolgirl Outfit"
|
|
her_outfit_fishnet.name = "Fishnet Set"
|
|
her_outfit_cheerleader_1.name = "Gryffindor Cheerleader Uniform"
|
|
her_outfit_cheerleader_2.name = "Gryffindor Cheerleader Plus Uniform"
|
|
lun_outfit_bikini3.name = "Rave Bikini Set"
|
|
ton_outfit_bikini_1.name = "Simple Bikini set"
|
|
ton_outfit_bikini_2.name = "Striped Bikini set"
|
|
|
|
quidditchguide_ITEM.price = 100
|
|
|
|
for i in inventory.items:
|
|
if hasattr(i, "infinite"):
|
|
continue
|
|
|
|
setattr(i, "infinite", False)
|
|
i.infinite = False
|
|
|
|
### Start Update 'Admire Panties' event
|
|
|
|
# Store states
|
|
ev_tier = hg_pf_admire_panties.tier
|
|
ev_in_progress = hg_pf_admire_panties.inProgress
|
|
ev_counter = hg_pf_admire_panties.counter
|
|
|
|
# Remove old pointer from favour list
|
|
hg_favor_list.remove(hg_pf_admire_panties)
|
|
|
|
# Re-run default statement
|
|
reset_variables("hg_pf_admire_panties")
|
|
|
|
# Restore state
|
|
hg_pf_admire_panties.tier = ev_tier
|
|
hg_pf_admire_panties.inProgress = ev_in_progress
|
|
hg_pf_admire_panties.counter = ev_counter
|
|
|
|
# Mark events from tier below as completed
|
|
if ev_tier > 1:
|
|
for i in xrange(ev_tier):
|
|
for ev in hg_pf_admire_panties.events[i]:
|
|
ev[1] = True
|
|
|
|
# Add new pointer to favour list
|
|
hg_favor_list.append(hg_pf_admire_panties)
|
|
|
|
### End Update 'Admire Panties' event
|
|
|
|
leg2_scroll_ITEM.label = "leg2_scroll"
|
|
|
|
global sna_support, ton_support
|
|
|
|
del sna_support
|
|
del ton_support
|
|
|
|
preferences.renderer = "angle2" if renpy.windows else "gl2"
|
|
|
|
# Update tooltip scope
|
|
|
|
renpy.hide_screen("tooltip")
|
|
renpy.show_screen("tooltip")
|
|
|
|
# Reset house points (Required to ensure balance isn't affected)
|
|
global gryffindor, slytherin, ravenclaw, hufflepuff
|
|
|
|
gryffindor, slytherin, ravenclaw, hufflepuff = 400, 500, 500, 500
|
|
|
|
# Update Outfits Addons
|
|
her_outfit_pajama.group = [her_hair_base.clone(), her_top_pajama.clone(), her_bottom_pajama.clone()]
|
|
her_outfit_pajama.addons = [her_bottom_pajama2]
|
|
|
|
her_outfit_maid.group = [her_hair_base.clone(), her_top_maid1.clone(), her_stockings_maid1.clone(), her_hat_maid1.clone(), her_neckwear_maid1.clone(), her_gloves_maid1.clone(), her_panties_base1.clone(), her_bra_base1.clone()]
|
|
her_outfit_maid.addons = [her_neckwear_maid2]
|
|
|
|
her_outfit_xmas.group = [her_hair_base.clone(), her_hat_antlers.clone(), her_neckwear_bell1.clone(), her_top_xmas.clone(), her_bottom_xmas.clone(), her_gloves_xmas.clone(), her_stockings_xmas.clone(), her_panties_base1.clone()]
|
|
her_outfit_xmas.addons = [her_hat_elf]
|
|
|
|
ton_outfit_succubus.group = [ton_hair_base_new.clone(), ton_hat_succubus.clone(), ton_neckwear_succubus.clone(), ton_gloves_succubus.clone(), ton_top_succubus.clone(), ton_panties_succubus.clone(), ton_accessory0_succubus.clone(), ton_accessory1_succubus.clone()]
|
|
ton_outfit_succubus.addons = [ton_top_succubus2]
|
|
|
|
ton_outfit_xmas.group = [ton_hair_base_new.clone(), ton_hat_antlers.clone(), ton_earring_bells.clone(), ton_neckwear_bell1.clone(), ton_bra_pasties2.clone(), ton_bottom_xmas.clone(), ton_gloves_xmas.clone(), ton_stockings_xmas.clone()]
|
|
ton_outfit_xmas.addons = [ton_piercing1_nipple_bells, ton_bra_pasties2]
|
|
|
|
# Update tonks' bikini
|
|
ton_panties_base.color_default = [[228, 250, 255, 255], [228, 55, 20, 255]]
|
|
ton_bra_base.color_default = [[228, 250, 255, 255], [228, 55, 20, 255]]
|
|
|
|
ton_panties_base.set_layers()
|
|
ton_bra_base.set_layers()
|
|
|
|
for i in CHARACTERS:
|
|
char = getattr(renpy.store, i)
|
|
|
|
for outfit in char.outfits:
|
|
if hasattr(outfit, "addons"):
|
|
continue
|
|
|
|
setattr(outfit, "addons", [])
|
|
|
|
char.rebuild()
|
|
|
|
# Add new backside layer for Hermione, and update zorders
|
|
hermione.body.body.update({"backside": [None, 1],})
|
|
hermione.body.set_zorder(armright=-1, base=0)
|
|
|
|
# Update CG camera object
|
|
camera.min_zoom = 0.1
|
|
|
|
# Didn't we remove that in last patch?
|
|
if hasattr(renpy.store, "hg_pr_sex_skip"):
|
|
delattr(renpy.store, "hg_pr_sex_skip")
|
|
|
|
# Update room objects
|
|
fireplace_OBJ.tooltip = "Light/Extinguish"
|
|
trophy_OBJ.pos = (650, 120)
|
|
|
|
if current < 1.411:
|
|
ton_gloves_leather.armfix = True
|
|
ton_gloves_leather.set_layers()
|
|
|
|
for i in CHARACTERS:
|
|
char = getattr(renpy.store, i)
|
|
|
|
char.rebuild()
|
|
|
|
setattr(renpy.store, "inventory_mode", 0)
|
|
|
|
if ll_pf_inspect.is_event_complete(2, 3):
|
|
hair_luna_ITEM.owned = 1
|
|
|
|
if current < 1.412:
|
|
message = "Happy halloween!"
|
|
|
|
# Fix luna levels
|
|
setattr(cho_hat_catears, "level", 10)
|
|
setattr(lun_top_crop, "level", 7)
|
|
setattr(lun_panties_lace2, "level", 7)
|
|
setattr(lun_stockings_muggle_knee_socks, "categories", ("legwear", "stockings"))
|
|
|
|
for i in inventory.items:
|
|
# Fix general items
|
|
if not hasattr(i, "give_label"):
|
|
setattr(i, "give_label", None)
|
|
if not hasattr(i, "usable_on"):
|
|
setattr(i, "usable_on", [])
|
|
|
|
# Fix decorations
|
|
if i.type == "decoration":
|
|
if not hasattr(i, "replaces"):
|
|
setattr(i, "replaces", False)
|
|
if not hasattr(i, "use_action"):
|
|
setattr(i, "use_action", None)
|
|
if not hasattr(i, "replace_action"):
|
|
setattr(i, "replace_action", None)
|
|
if not hasattr(i, "room_image_hover"):
|
|
setattr(i, "room_image_hover", i.room_image)
|
|
|
|
elif i.type == "gift":
|
|
setattr(i, "usable_on", list(CHARACTERS))
|
|
|
|
setattr(collar_ITEM, "name", "Magic Collar")
|
|
setattr(collar_ITEM, "price", 500)
|
|
setattr(collar_ITEM, "givable", True)
|
|
setattr(collar_ITEM, "give_label", "collar_scene")
|
|
setattr(collar_ITEM, "caption", "Give")
|
|
setattr(collar_ITEM, "usable_on", ["hermione"])
|
|
setattr(collar_ITEM, "unlocked", True)
|
|
setattr(collar_ITEM, "label", None)
|
|
setattr(collar_ITEM, "usable", False)
|
|
setattr(collar_ITEM, "desc", "{size=-2}A collar made out of metal. It has an inscription on the back.\n\n{/size}{size=-2}{i}\"Transforms to show the wearers true self.\n WARNING: May cause harm to adjacent clothing during transformation.\"{/i}{/size}")
|
|
setattr(collar_ITEM, "limit", 100)
|
|
|
|
setattr(halloween_phoenix_ITEM, "name", "Phoenix Halloween Set")
|
|
setattr(halloween_phoenix_ITEM, "desc", "A Halloween themed set for your favourite bird!")
|
|
setattr(halloween_fireplace_ITEM, "desc", "Adds a spooky pumpkin near your fireplace!")
|
|
setattr(halloween_cupboard, "name", "Cupboard Pumpkin")
|
|
setattr(halloween_cupboard, "desc", "Get in the Halloween spirit with this pumpkin, nobody's eating them so might as well decorate with them!")
|
|
|
|
# Fix room objects
|
|
setattr(candleL_OBJ, "focus_mask", True)
|
|
setattr(candleR_OBJ, "focus_mask", True)
|
|
setattr(candleL_OBJ, "zorder", 3)
|
|
setattr(candleR_OBJ, "zorder", 3)
|
|
|
|
# Rebuild models
|
|
for i in CHARACTERS:
|
|
char = getattr(renpy.store, i)
|
|
|
|
char.rebuild()
|
|
|
|
if current < 1.413:
|
|
message = "Happy halloween!"
|
|
|
|
if getattr(renpy.store, "room_menu_active"):
|
|
renpy.hide_screen("with_snape")
|
|
renpy.hide_screen("with_tonks_animated")
|
|
renpy.hide_screen("tonks_sit_ani")
|
|
renpy.hide_screen("tonks_sit_ani")
|
|
renpy.hide_screen("snape_chibi")
|
|
|
|
if current < 1.414:
|
|
message = "Happy Holidays!"
|
|
|
|
for i in inventory.items:
|
|
if i.type == "decoration":
|
|
if not hasattr(i, "replace_anchor"):
|
|
setattr(i, "replace_anchor", None)
|
|
setattr(i, "replace_pos", None)
|
|
|
|
# To fix hover images we need to dive into children of the hover transform displayable,
|
|
# and see if the child is None, in which case it should be replaced with the base room image.
|
|
# Animations (blink) are added on show events so it's irrevelant.
|
|
|
|
if i.room_image_hover and i.room_image_hover.child is None:
|
|
i.room_image_hover = i.room_image
|
|
|
|
ton_panties_succubus.armfix = True
|
|
tonks.rebuild()
|
|
|
|
# Power saving results in flickering on Intel Xe graphics units and low performance on some android devices. (probably a symptom rather than a cause)
|
|
preferences.gl_powersave = False
|
|
|
|
if current < 1.42:
|
|
message = "Happy April 1st! \n{size=-4}Disclaimer: This update is no joke, it's totaly real!{/size}"
|
|
|
|
# Update Cho clothes
|
|
|
|
choq_cloth_robequidditch1.armfix = False
|
|
choq_cloth_robequidditch1.color_default = [[60, 78, 131, 255], [186, 141, 11, 255]]
|
|
choq_cloth_robequidditch1.reset_color()
|
|
choq_cloth_topsweater1.armfix = False
|
|
choq_cloth_topsweater1.color_default = [[60, 78, 131, 255], [186, 141, 11, 255]]
|
|
choq_cloth_topsweater1.reset_color()
|
|
choq_cloth_pantslong2.armfix = False
|
|
choq_cloth_pantsshort4.armfix = False
|
|
cho_outfit_quidditch.group = [choq_cloth_topsweater1, choq_cloth_pantslong2, choq_cloth_robequidditch1, choq_bra_sports1, choq_panties_sport1]
|
|
cho_outfit_quidditch_hufflepuff.group = [choq_cloth_topsweater1, choq_cloth_schoolskirt2, choq_cloth_robequidditch1, choq_accessory_protectors, choq_bra_sports1, choq_panties_sport1]
|
|
cho_outfit_quidditch_slytherin.group = [choq_cloth_topsweater1, choq_cloth_pantslong2, choq_accessory_protectors2, choq_bra_sports1, choq_panties_sport1]
|
|
cho_outfit_quidditch_gryffindor.group = [choq_cloth_topsweater1, choq_cloth_schoolskirt3, choq_accessory_protectors, choq_bra_sports1, choq_panties_sport1]
|
|
|
|
# Update chitchat states and delete old vars from memory.
|
|
setattr(renpy.store, "snape_chatted", chitchated_with_snape)
|
|
setattr(renpy.store, "tonks_chatted", chitchated_with_tonks)
|
|
setattr(renpy.store, "hermione_chatted", chitchated_with_hermione)
|
|
setattr(renpy.store, "luna_chatted", chitchated_with_luna)
|
|
setattr(renpy.store, "cho_chatted", chitchated_with_cho)
|
|
setattr(renpy.store, "astoria_chatted", chitchated_with_astoria)
|
|
setattr(renpy.store, "susan_chatted", chitchated_with_susan)
|
|
|
|
delattr(renpy.store, "chitchated_with_snape")
|
|
delattr(renpy.store, "chitchated_with_tonks")
|
|
delattr(renpy.store, "chitchated_with_hermione")
|
|
delattr(renpy.store, "chitchated_with_luna")
|
|
delattr(renpy.store, "chitchated_with_cho")
|
|
delattr(renpy.store, "chitchated_with_astoria")
|
|
delattr(renpy.store, "chitchated_with_susan")
|
|
|
|
# Quidditch
|
|
setattr(cho_quid, "E10_complete", False)
|
|
setattr(cho_quid, "E11_complete", False)
|
|
setattr(cho_quid, "E12_complete", False)
|
|
setattr(cho_quid, "E13_complete", False)
|
|
setattr(cho_quid, "gryffindor_failed", False)
|
|
setattr(cho_quid, "gryffindor_prepared", False)
|
|
setattr(cho_quid, "gryffindor_training", False)
|
|
setattr(cho_quid, "gryffindor_complete", False)
|
|
|
|
# Tonks
|
|
|
|
setattr(renpy.store, "tonks_wardrobe_unlocked", True)
|
|
|
|
### Start Update 'Talk To Me' events
|
|
|
|
# Store states
|
|
ev_tier = cc_pf_talk.tier
|
|
ev_in_progress = cc_pf_talk.inProgress
|
|
ev_counter = cc_pf_talk.counter
|
|
|
|
# Remove old pointer from favour list
|
|
cc_favor_list.remove(cc_pf_talk)
|
|
|
|
# Re-run default statement
|
|
reset_variables("cc_pf_talk")
|
|
|
|
# Restore state
|
|
cc_pf_talk.tier = ev_tier
|
|
cc_pf_talk.inProgress = ev_in_progress
|
|
cc_pf_talk.counter = ev_counter
|
|
|
|
# Mark events from tier below as completed
|
|
|
|
# TODO: This might cause some events from current tier to be skipped.
|
|
# It would be better to use deepcopy on the list instead.
|
|
|
|
if ev_tier > 1:
|
|
for i in xrange(ev_tier):
|
|
for ev in cc_pf_talk.events[i]:
|
|
ev[1] = True
|
|
|
|
# Add new pointer to favour list
|
|
cc_favor_list.append(cc_pf_talk)
|
|
cho.rebuild()
|
|
|
|
# Reverse whoring cheat, otherwise the player would be locked out of some paths.
|
|
if getattr(renpy.store, "cho_whoring") >= 12:
|
|
setattr(renpy.store, "cho_whoring", 12)
|
|
|
|
# Update camera
|
|
camera.max_zoom = 5.0
|
|
|
|
### End Update 'Talk To Me' event
|
|
|
|
if current < 1.421:
|
|
message = "Happy April 1st!"
|
|
|
|
hooch.equip(hoo_outfit_default)
|
|
|
|
cho_outfit_quidditch.group = [choq_cloth_topsweater1.clone(), choq_cloth_pantslong2.clone(), choq_cloth_robequidditch1.clone(), choq_bra_sports1.clone(), choq_panties_sport1.clone()]
|
|
cho_outfit_quidditch_hufflepuff.group = [choq_cloth_topsweater1.clone(), choq_cloth_schoolskirt2.clone(), choq_cloth_robequidditch1.clone(), choq_accessory_protectors.clone(), choq_bra_sports1.clone(), choq_panties_sport1.clone()]
|
|
cho_outfit_quidditch_slytherin.group = [choq_cloth_topsweater1.clone(), choq_cloth_pantslong2.clone(), choq_accessory_protectors2.clone(), choq_bra_sports1.clone(), choq_panties_sport1.clone()]
|
|
cho_outfit_quidditch_gryffindor.group = [choq_cloth_topsweater1.clone(), choq_cloth_schoolskirt3.clone(), choq_accessory_protectors.clone(), choq_bra_sports1.clone(), choq_panties_sport1.clone()]
|
|
|
|
if current < 1.422:
|
|
message = ""
|
|
|
|
hooch.equip(hoo_outfit_default)
|
|
|
|
cho_outfit_quidditch.group = [cho_hair_ponytail1.clone(), choq_cloth_topsweater1.clone(), choq_cloth_pantslong2.clone(), choq_cloth_robequidditch1.clone(), choq_bra_sports1.clone(), choq_panties_sport1.clone()]
|
|
cho_outfit_quidditch_hufflepuff.group = [cho_hair_ponytail1.clone(), choq_cloth_topsweater1.clone(), choq_cloth_schoolskirt2.clone(), choq_cloth_robequidditch1.clone(), choq_accessory_protectors.clone(), choq_bra_sports1.clone(), choq_panties_sport1.clone()]
|
|
cho_outfit_quidditch_slytherin.group = [cho_hair_ponytail1.clone(), choq_cloth_topsweater1.clone(), choq_cloth_pantslong2.clone(), choq_accessory_protectors2.clone(), choq_bra_sports1.clone(), choq_panties_sport1.clone()]
|
|
cho_outfit_quidditch_gryffindor.group = [cho_hair_ponytail1.clone(), choq_cloth_topsweater1.clone(), choq_cloth_schoolskirt3.clone(), choq_accessory_protectors.clone(), choq_bra_sports1.clone(), choq_panties_sport1.clone()]
|
|
|
|
cho.rebuild()
|
|
|
|
|
|
renpy.call_in_new_context("modal_popup", "Update Successful", "\nYour save file has been successfully updated to version {{b}}{}{{/b}}.\n\n{}".format(config.version, message), None, "Hurray!")
|
|
renpy.block_rollback()
|
|
return
|
|
|
|
def version_upgrade():
|
|
|
|
if config.developer:
|
|
return
|
|
|
|
if renpy.mobile:
|
|
return
|
|
|
|
def get_patch(files, deep=False):
|
|
prefix = config.gamedir if deep else config.basedir
|
|
archives = [os.path.join(prefix, x) for x in files if x == "patch.zip"]
|
|
|
|
if not archives:
|
|
return None
|
|
|
|
file = max(archives, key=os.path.getmtime)
|
|
return file
|
|
|
|
def get_progress(files):
|
|
for i, _ in enumerate(files):
|
|
print i
|
|
|
|
print "Searching for an archive..."
|
|
|
|
# Base search
|
|
files = [x for x in os.listdir(config.basedir) if os.path.isfile(x)]
|
|
patch = get_patch(files)
|
|
|
|
# Deep search
|
|
if not patch:
|
|
files = renpy.list_files()
|
|
patch = get_patch(files, deep=True)
|
|
|
|
if not patch:
|
|
print "No update packages detected. Skipping."
|
|
return
|
|
|
|
print "Archive found.\n{}".format(patch)
|
|
|
|
with zipfile.ZipFile(patch, "r") as zip:
|
|
print "Testing archive..."
|
|
corrupted = zip.testzip()
|
|
|
|
if corrupted:
|
|
print "Cannot perform an upgrade. File is corrupted."
|
|
return
|
|
|
|
print "Checking manifest..."
|
|
contents = zip.namelist()
|
|
|
|
if not "manifest.json" in contents:
|
|
print "Cannot perform an upgrade. Manifest not found."
|
|
return
|
|
|
|
with zip.open("manifest.json") as manifest:
|
|
data = json.load(manifest)
|
|
target = data.get("Target", None)
|
|
|
|
if not target:
|
|
print "Cannot perform an upgrade. Manifest is missing a target."
|
|
return
|
|
|
|
current = version_float()
|
|
|
|
if current >= float(target):
|
|
print "Cannot perform an upgrade. Equal or higher version already installed."
|
|
return
|
|
|
|
delete = data.get("Delete", [])
|
|
|
|
for f in delete:
|
|
status = remove_file(f)
|
|
if status == 2:
|
|
# Lacking permissions
|
|
if renpy.windows and not is_admin():
|
|
ask_admin()
|
|
renpy.quit()
|
|
|
|
print "Backing up files..."
|
|
src = os.path.join(config.basedir, "game/scripts/")
|
|
dest = os.path.join(config.basedir, "old-game/scripts/")
|
|
|
|
if os.path.isdir(dest):
|
|
shutil.rmtree(dest)
|
|
copytree(src, dest)
|
|
|
|
print "Unpacking..."
|
|
zip.extractall(config.basedir, members=get_progress(contents))
|
|
|
|
remove_file("instructions.txt")
|
|
remove_file("DO NOT EXTRACT!")
|
|
remove_file("hotfix.zip")
|
|
|
|
src = patch
|
|
dest = os.path.join(config.basedir, "old_patch.zip")
|
|
|
|
if os.path.isfile(dest):
|
|
remove_file(dest)
|
|
|
|
os.rename(src, dest)
|
|
print "Done."
|
|
print "Restarting..."
|
|
renpy.quit(relaunch=True)
|
|
|
|
version_upgrade()
|
|
|
|
init python:
|
|
config.after_load_callbacks.append(version_patch)
|
|
|
|
label before_main_menu():
|
|
# Add screen
|
|
return
|