forked from tf2classic/TF2CDownloader
-
Notifications
You must be signed in to change notification settings - Fork 0
/
versions.py
123 lines (110 loc) · 5.01 KB
/
versions.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
from os import path
from subprocess import run
from platform import system
from gettext import gettext as _
from gettext import ngettext as _N
import urllib.request
import gui
import vars
import json
VERSION_LIST = None
PATCH_CHAIN = None
def get_version_list():
global VERSION_LIST
if VERSION_LIST is None:
try:
VERSION_LIST = json.loads(urllib.request.urlopen(vars.SOURCE_URL + 'versions.json').read())
except urllib.error.URLError:
gui.message_end(_("Could not get version list. If your internet connection is fine, the servers could be having technical issues."), 1)
return VERSION_LIST
def update_version_file():
"""
The previous launcher/updater leaves behind a rev.txt file with the old internal revision number.
To avoid file bloat, we reuse this, but replace it with the game's semantic version number.
To obtain the game's semantic version number, we do some horrible parsing of the game's version.txt
file, which is what the game itself uses directly to show the version number on the main menu, etc.
"""
try:
old_version_file = open(vars.INSTALL_PATH + '/tf2classic/version.txt', 'r')
except FileNotFoundError:
if gui.message_yes_no(_("We can't read the version of your installation. It could be corrupted. Do you want to reinstall the game?"), False):
return False
else:
gui.message_end(_("We have nothing to do. Goodbye!"), 0)
old_version = old_version_file.readlines()[1]
before, sep, after = old_version.partition('=')
if len(after) > 0:
old_version = after
old_version = old_version.replace('.', '')
new_version_file = open(vars.INSTALL_PATH + '/tf2classic/rev.txt', 'w')
# We unconditionally overwrite rev.txt since version.txt is the canonical file.
new_version_file.write(old_version)
new_version_file.close()
old_version_file.close()
return True
def patch_chain(ver_from, ver_to):
current_version = ver_from
global PATCH_CHAIN
PATCH_CHAIN = []
while current_version != ver_to:
if not current_version in VERSION_LIST["patches"]:
# still not in the latest version, could not find patch
return False
patch = VERSION_LIST["patches"][current_version]
patch["from"] = current_version
if "file" not in patch:
patch["file"] = patch["url"]
if patch in PATCH_CHAIN:
# somehow managed to get ourselves into a loop, avoid the memory hogging infinite loop, killer of desktops
return False
PATCH_CHAIN.append(patch)
current_version = patch["to"]
return True
def get_patch_chain():
global PATCH_CHAIN
return PATCH_CHAIN
def check_for_updates():
"""
It's all math here. We can compare the version number against remote variables to see what we should do.
"""
# This probably was already communicated to the user in update_version_file(), but if version.txt doesn't exist, skip updating.
if not path.exists(vars.INSTALL_PATH + '/tf2classic/version.txt'):
return 'reinstall'
try:
local_version_file = open(vars.INSTALL_PATH + '/tf2classic/rev.txt', 'r')
local_version = local_version_file.read()
except ValueError:
if gui.message_yes_no(_("We can't read the version of your installation. It could be corrupted. Do you want to reinstall the game?"), False):
return 'reinstall'
else:
gui.message_end(_("We have nothing to do. Goodbye!"), 0)
found = False
for ver in VERSION_LIST["versions"]:
if ver["ver"] == local_version:
found = True
break
if not found:
if gui.message_yes_no(_("The version of your installation is unknown. It could be corrupted. Do you want to reinstall the game?"), False):
return 'reinstall'
else:
gui.message_end(_("We have nothing to do. Goodbye!"), 0)
latest_version = VERSION_LIST["versions"][-1]["ver"]
if local_version == latest_version:
if gui.message_yes_no(_("We think we've found an existing up-to-date installation of the game. Do you want to reinstall it?"), False):
return 'reinstall'
else:
gui.message_end(_("We have nothing to do. Goodbye!"), 0)
if patch_chain(local_version, latest_version):
if gui.message_yes_no(_("An update is available for your game. Do you want to install it?"), 0):
return 'update'
else:
if gui.message_yes_no(_("In that case, do you want to reinstall completely?"), 0):
return 'reinstall'
else:
gui.message_end(_("We have nothing to do. Goodbye!"), 0)
else:
# We did not find an applicable patch chain to properly update the game, forcing us to relie on the ol' reinstallation method.
if gui.message_yes_no(_("An update is available for your game. Do you want to install it?"), 0):
return 'reinstall'
else:
gui.message_end(_("We have nothing to do. Goodbye!"), 0)