Skip to content

Commit 34fdf9c

Browse files
committed
add updater window
1 parent 687bfdf commit 34fdf9c

File tree

4 files changed

+174
-12
lines changed

4 files changed

+174
-12
lines changed

gui/index.html

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -316,5 +316,4 @@ <h2>Install Folder</h2>
316316
})
317317
</script>
318318
</body>
319-
320-
</html>
319+
</html>

gui/update.html

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
<!doctype html>
2+
<html lang="en">
3+
4+
<head>
5+
<meta charset="utf-8">
6+
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
7+
<title>Team Comtress Launcher</title>
8+
<style>
9+
* {
10+
box-sizing: border-box;
11+
}
12+
13+
html {
14+
scrollbar-width: thin;
15+
scrollbar-color: rgb(0, 150, 136) rgb(33, 37, 41);
16+
scroll-padding-top: 89px;
17+
scroll-behavior: smooth;
18+
overflow-x: hidden;
19+
overflow-y: hidden;
20+
color-scheme: dark;
21+
}
22+
23+
body {
24+
color-scheme: dark;
25+
background-color: rgb(33, 33, 33);
26+
color: rgb(222, 226, 230);
27+
font-family: "Roboto Flex Variable", -apple-system, BlinkMacSystemFont, "Segoe UI", "Helvetica Neue", Arial, sans-serif;
28+
font-size: 16px;
29+
font-weight: 400;
30+
letter-spacing: 0.1px;
31+
line-height: 24px;
32+
margin: 0;
33+
text-align: start;
34+
overflow-x: hidden;
35+
overflow-y: hidden;
36+
height: 100vh;
37+
width: 100vw;
38+
}
39+
40+
#logo-container {
41+
text-align: center;
42+
}
43+
44+
#app {
45+
display: flex;
46+
justify-content: center;
47+
align-items: center;
48+
height: 100vh;
49+
width: 100vw;
50+
}
51+
52+
.logo {
53+
width: min(70vw, 400px);
54+
height: auto;
55+
}
56+
</style>
57+
</head>
58+
59+
<body>
60+
<div id="app">
61+
<div id="logo-container">
62+
<img src="tc2.png" class="logo" />
63+
<h1>Updating...</h1>
64+
</div>
65+
</div>
66+
</body>
67+
</html>

tc2_launcher/__main__.py

Lines changed: 43 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
import argparse
22
import multiprocessing
3+
import queue
34
import sys
5+
import threading
46
from pathlib import Path
57
from shutil import copyfile
68
from time import sleep
79
from timeit import default_timer as timer
10+
from typing import Optional
811

9-
from tc2_launcher.gui import start_gui
12+
from tc2_launcher.gui import close_gui, start_gui, start_gui_separate
1013
from tc2_launcher.run import (
1114
DEV_INSTANCE,
1215
clean_self_update,
@@ -19,10 +22,42 @@
1922

2023
version = "0.6.0"
2124

25+
updater_thread_queue: Optional[queue.Queue] = None
26+
should_launch_updater = True
27+
28+
29+
def updater_thread():
30+
global updater_thread_queue
31+
sleep(0.5)
32+
if not should_launch_updater:
33+
return
34+
p, q = start_gui_separate("update", frameless=True, easy_drag=True)
35+
if updater_thread_queue:
36+
q.put(updater_thread_queue.get())
37+
updater_thread_queue = None
38+
39+
40+
def start_updater_gui():
41+
global updater_thread_queue
42+
updater_thread_queue = queue.Queue()
43+
threading.Thread(target=updater_thread).start()
44+
45+
46+
def close_updater_gui():
47+
global updater_thread_queue
48+
if updater_thread_queue:
49+
updater_thread_queue.put("close")
50+
2251

2352
def main():
53+
global should_launch_updater
2454
launch_gui = False
2555
if len(sys.argv) >= 3 and sys.argv[1] == "--replace":
56+
launch_gui = len(sys.argv) == 3
57+
58+
if launch_gui:
59+
start_updater_gui()
60+
2661
# Replacement mode after self-update
2762
try:
2863
original_path = Path(sys.argv[2]).resolve()
@@ -52,13 +87,18 @@ def main():
5287
except Exception as e:
5388
print(f"ERROR: Failed to apply self-update: {e}")
5489

55-
launch_gui = len(sys.argv) == 3
90+
close_updater_gui()
5691
else:
92+
launch_gui = len(sys.argv) == 1
93+
if launch_gui:
94+
start_updater_gui()
95+
5796
if not DEV_INSTANCE and update_self(version):
5897
sys.exit(0)
5998
return
6099

61-
launch_gui = len(sys.argv) == 1
100+
should_launch_updater = False
101+
close_updater_gui()
62102

63103
clean_self_update()
64104

tc2_launcher/gui.py

Lines changed: 63 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
1+
import multiprocessing
12
import os
23
import subprocess
34
import sys
5+
import threading
46
from pathlib import Path
7+
from typing import Optional
58

69
import webview
710

@@ -28,14 +31,14 @@ def exists(path):
2831
if path.exists():
2932
return path
3033

31-
queries = ["../gui/index.html", "../Resources/gui/index.html", "./gui/index.html"]
34+
queries = ["../gui", "../Resources/gui", "./gui"]
3235

3336
for query in queries:
3437
result = exists(query)
3538
if result:
3639
return result
3740

38-
raise Exception("No index.html found")
41+
raise Exception("No gui directory found")
3942

4043

4144
class Api:
@@ -93,21 +96,74 @@ def check_launch_game(time_limit: float = 0):
9396
return False
9497

9598

99+
def check_queue():
100+
while True:
101+
if not current_queue:
102+
return
103+
cmd = current_queue.get()
104+
if cmd == "close":
105+
close_gui()
106+
return
107+
108+
96109
def on_loaded(window):
110+
if current_queue:
111+
threading.Thread(target=check_queue).start()
112+
if current_entry != "index":
113+
return
97114
if not check_launch_game(-1):
98115
update_and_notify(window)
99116

100117

101-
entry_path = get_entrypoint()
102-
entry = str(entry_path)
103-
entry_parent = entry_path.parent
118+
entry_parent = get_entrypoint()
119+
current_entry: str | None = None
120+
current_queue: Optional[multiprocessing.Queue] = None
121+
122+
123+
def close_gui():
124+
window = get_window()
125+
window.destroy()
126+
127+
128+
def start_gui_separate(entry_name: str = "index", **kwargs):
129+
q = multiprocessing.Queue()
130+
p = multiprocessing.Process(
131+
target=_start_gui_private, args=(entry_name, q), kwargs=kwargs
132+
)
133+
p.start()
134+
return p, q
135+
136+
137+
def start_gui(entry_name: str = "index", **kwargs):
138+
_start_gui_private(entry_name, **kwargs)
104139

105140

106-
def start_gui():
141+
def _start_gui_private(
142+
entry_name: str = "index", queue: Optional[multiprocessing.Queue] = None, **kwargs
143+
):
144+
global current_entry
145+
global current_queue
107146
extra_options = get_launch_options()
108147
extra_options_str = " ".join(extra_options)
148+
entry = str(entry_parent / f"{entry_name}.html")
149+
current_entry = entry_name
150+
current_queue = queue
151+
width = 800
152+
height = 600
153+
min_size = (640, 360)
154+
if entry_name == "update":
155+
width = 400
156+
height = 533
157+
min_size = (400, 533)
109158
window = webview.create_window(
110-
"Team Comtress Launcher", entry, js_api=Api(), min_size=(640, 360)
159+
"Team Comtress Launcher",
160+
entry,
161+
js_api=Api(),
162+
min_size=min_size,
163+
width=width,
164+
height=height,
165+
background_color="#212121",
166+
**kwargs,
111167
)
112168
if window:
113169
window.state.opts = extra_options_str

0 commit comments

Comments
 (0)