Skip to content

Commit 492dd09

Browse files
committed
basic installer
0 parents  commit 492dd09

File tree

14 files changed

+1624
-0
lines changed

14 files changed

+1624
-0
lines changed

.gitignore

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
# Byte-compiled / optimized / DLL files
2+
__pycache__/
3+
*.py[cod]
4+
*$py.class
5+
6+
# C extensions
7+
*.so
8+
9+
# Distribution / packaging
10+
.Python
11+
build/
12+
develop-eggs/
13+
dist/
14+
downloads/
15+
eggs/
16+
.eggs/
17+
lib/
18+
lib64/
19+
parts/
20+
sdist/
21+
var/
22+
wheels/
23+
*.egg-info/
24+
.installed.cfg
25+
*.egg
26+
MANIFEST
27+
28+
# PyInstaller
29+
# Usually these files are written by a python script from a template
30+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
31+
*.manifest
32+
33+
# Installer logs
34+
pip-log.txt
35+
pip-delete-this-directory.txt
36+
37+
# Unit test / coverage reports
38+
htmlcov/
39+
.tox/
40+
.coverage
41+
.coverage.*
42+
.cache
43+
nosetests.xml
44+
coverage.xml
45+
*.cover
46+
.hypothesis/
47+
.pytest_cache/
48+
49+
# Translations
50+
*.mo
51+
*.pot
52+
53+
# Django stuff:
54+
*.log
55+
local_settings.py
56+
db.sqlite3
57+
58+
# Flask stuff:
59+
instance/
60+
.webassets-cache
61+
62+
# Scrapy stuff:
63+
.scrapy
64+
65+
# Sphinx documentation
66+
docs/_build/
67+
68+
# PyBuilder
69+
target/
70+
71+
# Jupyter Notebook
72+
.ipynb_checkpoints
73+
74+
# celery beat schedule file
75+
celerybeat-schedule
76+
77+
# SageMath parsed files
78+
*.sage.py
79+
80+
# Environments
81+
.venv
82+
env/
83+
venv/
84+
ENV/
85+
env.bak/
86+
venv.bak/
87+
88+
# Spyder project settings
89+
.spyderproject
90+
.spyproject
91+
92+
# Rope project settings
93+
.ropeproject
94+
95+
# mkdocs documentation
96+
/site
97+
98+
# mypy
99+
.mypy_cache/
100+
101+
#vs code
102+
.vscode/*.json
103+
!.vscode/launch.json
104+
105+
# pycharm
106+
.idea

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2025 mastercoms
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# TC2 Launcher
2+
3+
Manages downloading and launching TC2.

build-windows.spec

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
# -*- mode: python ; coding: utf-8 -*-
2+
3+
options = [
4+
("X utf8", None, "OPTION"),
5+
("hash_seed=0", None, "OPTION"),
6+
("O", None, "OPTION"),
7+
]
8+
9+
block_cipher = None
10+
added_files = [
11+
(".\\gui", "gui"),
12+
]
13+
14+
a = Analysis(
15+
[".\\tc2_launcher\\__main__.py"],
16+
pathex=["."],
17+
binaries=[],
18+
datas=added_files,
19+
hiddenimports=["clr"],
20+
hookspath=["hooks"],
21+
hooksconfig={},
22+
runtime_hooks=[],
23+
excludes=[],
24+
win_no_prefer_redirects=False,
25+
win_private_assemblies=False,
26+
cipher=block_cipher,
27+
noarchive=False,
28+
optimize=1,
29+
)
30+
31+
pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher)
32+
33+
exe = EXE(
34+
pyz,
35+
a.scripts,
36+
a.binaries,
37+
a.zipfiles,
38+
a.datas,
39+
options,
40+
name="TC2Launcher",
41+
debug=False,
42+
bootloader_ignore_signals=False,
43+
strip=False,
44+
upx=True,
45+
upx_exclude=[],
46+
runtime_tmpdir=None,
47+
console=False,
48+
disable_windowed_traceback=False,
49+
argv_emulation=False,
50+
target_arch=None,
51+
codesign_identity=None,
52+
entitlements_file=None,
53+
version="version.rc",
54+
icon=[".\\gui\\favicon.ico"],
55+
)

build.bat

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
@echo off
2+
set PYTHONUTF8=1
3+
set PYTHONOPTIMIZE=1
4+
set PYTHONHASHSEED=0
5+
set PYI_STATIC_ZLIB=1
6+
set OBJECT_MODE=64
7+
pyinstaller --clean build-windows.spec %*

gui/favicon.ico

285 KB
Binary file not shown.

gui/index.html

Lines changed: 198 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,198 @@
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+
padding-top: 1rem;
43+
}
44+
45+
#app {
46+
display: flex;
47+
flex-direction: column;
48+
justify-content: space-between;
49+
align-items: center;
50+
height: 100vh;
51+
width: 100vw;
52+
}
53+
54+
#launch-bar {
55+
display: flex;
56+
width: 100%;
57+
justify-content: center;
58+
padding: 1rem 1rem;
59+
background-color: rgb(255 255 255 / 5%);
60+
z-index: 10;
61+
}
62+
63+
.logo {
64+
width: min(70vw, 600px);
65+
height: auto;
66+
}
67+
68+
.btn {
69+
border: none;
70+
padding: 0.5rem 1rem;
71+
vertical-align: middle;
72+
}
73+
74+
.btn:hover:not(:disabled) {
75+
cursor: pointer;
76+
}
77+
78+
.btn-primary {
79+
background-color: rgb(0, 132, 120);
80+
}
81+
82+
.btn-primary:hover:not(:disabled) {
83+
background-color: rgb(0, 150, 136);
84+
}
85+
86+
.btn-secondary {
87+
background-color: rgb(97, 97, 97);
88+
color: white;
89+
}
90+
91+
.btn-secondary:hover:not(:disabled) {
92+
background-color: rgb(117, 117, 117);
93+
}
94+
95+
.btn-lg {
96+
font-size: 1.25rem;
97+
padding: 0.75rem 1.5rem;
98+
}
99+
100+
.spacer {
101+
flex-grow: 1;
102+
}
103+
104+
.menu {
105+
display: none;
106+
position: fixed;
107+
top: 0;
108+
left: 0;
109+
width: 100%;
110+
height: 100%;
111+
background-color: rgb(33, 33, 33);
112+
color: rgb(222, 226, 230);
113+
padding: 2rem;
114+
overflow-y: auto;
115+
z-index: 5;
116+
}
117+
118+
#launch-options {
119+
width: 100%;
120+
padding: 0.5rem;
121+
font-size: 1rem;
122+
margin-top: 0.5rem;
123+
}
124+
125+
.info-label {
126+
margin-right: 1rem;
127+
font-size: 1.25rem;
128+
vertical-align: middle;
129+
color: rgb(180, 180, 180);
130+
}
131+
</style>
132+
</head>
133+
134+
<body>
135+
<div id="app">
136+
<div id="logo-container">
137+
<img src="tc2.png" class="logo" />
138+
</div>
139+
<div id="launch-bar">
140+
<div class="spacer"></div>
141+
<div class="game-menu">
142+
<span class="info-label" style="display: none">Offline mode</span>
143+
<button id="launch-btn" class="btn btn-primary btn-lg" disabled>Updating...</button>
144+
<button id="settings-btn" class="btn btn-secondary btn-lg" title="Settings">
145+
<svg width="24" height="20" viewBox="0 0 24 20" fill="none" xmlns="http://www.w3.org/2000/svg">
146+
<path fill-rule="evenodd" clip-rule="evenodd"
147+
d="M7 3C8.86384 3 10.4299 4.27477 10.874 6H19V8H10.874C10.4299 9.72523 8.86384 11 7 11C4.79086 11 3 9.20914 3 7C3 4.79086 4.79086 3 7 3ZM7 9C8.10457 9 9 8.10457 9 7C9 5.89543 8.10457 5 7 5C5.89543 5 5 5.89543 5 7C5 8.10457 5.89543 9 7 9Z"
148+
fill="currentColor" />
149+
<path fill-rule="evenodd" clip-rule="evenodd"
150+
d="M17 20C15.1362 20 13.5701 18.7252 13.126 17H5V15H13.126C13.5701 13.2748 15.1362 12 17 12C19.2091 12 21 13.7909 21 16C21 18.2091 19.2091 20 17 20ZM17 18C18.1046 18 19 17.1046 19 16C19 14.8954 18.1046 14 17 14C15.8954 14 15 14.8954 15 16C15 17.1046 15.8954 18 17 18Z"
151+
fill="currentColor" />
152+
</svg>
153+
</button>
154+
</div>
155+
</div>
156+
</div>
157+
<div id="settings-menu" class="menu">
158+
<h1>Settings</h1>
159+
<h2>Launch Options</h2>
160+
<input id="launch-options" type="text"></input>
161+
<h2>Install Folder</h2>
162+
<button id="folder-btn" class="btn btn-secondary" disabled>Browse Install Folder</button>
163+
</div>
164+
<script>
165+
document.getElementById("launch-btn").addEventListener("click", () => {
166+
window.pywebview.api.launch_game();
167+
});
168+
document.getElementById("settings-btn").addEventListener("click", () => {
169+
const menu = document.getElementById("settings-menu");
170+
if (menu.style.display === "block") {
171+
menu.style.display = "none";
172+
} else {
173+
menu.style.display = "block";
174+
}
175+
});
176+
document.getElementById("launch-options").addEventListener("input", (event) => {
177+
window.pywebview.api.set_launch_options(options);
178+
});
179+
document.getElementById("folder-btn").addEventListener("click", () => {
180+
window.pywebview.api.open_install_folder();
181+
});
182+
function archiveReady(offline) {
183+
document.getElementById("launch-btn").disabled = false;
184+
document.getElementById("folder-btn").disabled = false;
185+
document.getElementById("launch-btn").innerText = "Launch";
186+
const online = offline === 0;
187+
if (!online) {
188+
document.querySelector(".info-label").innerText = "Offline mode";
189+
if (offline !== 1) {
190+
document.getElementById("launch-btn").innerText = "Install failed";
191+
}
192+
document.querySelector(".info-label").style.display = "inline";
193+
}
194+
}
195+
</script>
196+
</body>
197+
198+
</html>

gui/tc2.png

599 KB
Loading

0 commit comments

Comments
 (0)