forked from ClanGenOfficial/clangen
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.py
250 lines (189 loc) · 8.1 KB
/
main.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
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
#!/usr/bin/env python3
# pylint: disable=line-too-long
"""
This file is the main file for the game.
It also contains the main pygame loop
It first sets up logging, then loads the version hash from version.ini (if it exists), then loads the cats and clan.
It then loads the settings, and then loads the start screen.
""" # pylint: enable=line-too-long
import shutil
import sys
import time
import os
from scripts.housekeeping.log_cleanup import prune_logs
from scripts.stream_duplexer import UnbufferedStreamDuplexer
from scripts.datadir import get_log_dir, setup_data_dir
from scripts.version import get_version_info, VERSION_NAME
directory = os.path.dirname(__file__)
if directory:
os.chdir(directory)
if os.path.exists("auto-updated"):
print("Clangen starting, deleting auto-updated file")
os.remove("auto-updated")
shutil.rmtree("Downloads", ignore_errors=True)
print("Update Complete!")
print("New version: " + get_version_info().version_number)
setup_data_dir()
timestr = time.strftime("%Y%m%d_%H%M%S")
stdout_file = open(get_log_dir() + f'/stdout_{timestr}.log', 'a')
stderr_file = open(get_log_dir() + f'/stderr_{timestr}.log', 'a')
sys.stdout = UnbufferedStreamDuplexer(sys.stdout, stdout_file)
sys.stderr = UnbufferedStreamDuplexer(sys.stderr, stderr_file)
# Setup logging
import logging
formatter = logging.Formatter(
"%(name)s - %(levelname)s - %(filename)s / %(funcName)s / %(lineno)d - %(message)s"
)
# Logging for file
timestr = time.strftime("%Y%m%d_%H%M%S")
log_file_name = get_log_dir() + f"/clangen_{timestr}.log"
file_handler = logging.FileHandler(log_file_name)
file_handler.setFormatter(formatter)
# Only log errors to file
file_handler.setLevel(logging.ERROR)
# Logging for console
stream_handler = logging.StreamHandler()
stream_handler.setFormatter(formatter)
logging.root.addHandler(file_handler)
logging.root.addHandler(stream_handler)
prune_logs(logs_to_keep=5, retain_empty_logs=False)
def log_crash(logtype, value, tb):
"""
Log uncaught exceptions to file
"""
logging.critical("Uncaught exception", exc_info=(logtype, value, tb))
sys.__excepthook__(type, value, tb)
sys.excepthook = log_crash
# if user is developing in a github codespace
if os.environ.get('CODESPACES'):
print('')
print("Github codespace user!!! Sorry, but sound *may* not work :(")
print("SDL_AUDIODRIVER is dsl. This is to avoid ALSA errors, but it may disable sound.")
print('')
print("Web VNC:")
print(
f"https://{os.environ.get('CODESPACE_NAME')}-6080"
+ f".{os.environ.get('GITHUB_CODESPACES_PORT_FORWARDING_DOMAIN')}"
+ "/?autoconnect=true&reconnect=true&password=clangen&resize=scale")
print("(use clangen in fullscreen mode for best results)")
print('')
if get_version_info().is_source_build:
print("Running on source code")
if get_version_info().version_number == VERSION_NAME:
print("Failed to get git commit hash, using hardcoded version number instead.")
print("Hey testers! We recommend you use git to clone the repository, as it makes things easier for everyone.") # pylint: disable=line-too-long
print("There are instructions at https://discord.com/channels/1003759225522110524/1054942461178421289/1078170877117616169") # pylint: disable=line-too-long
else:
print("Running on PyInstaller build")
print("Version Name: ", VERSION_NAME)
print("Running on commit " + get_version_info().version_number)
# Load game
from scripts.game_structure.load_cat import load_cats, version_convert
from scripts.game_structure.windows import SaveCheck
from scripts.game_structure.game_essentials import game, MANAGER, screen
from scripts.game_structure.discord_rpc import _DiscordRPC
from scripts.cat.sprites import sprites
from scripts.clan import clan_class
from scripts.utility import get_text_box_theme, quit, scale # pylint: disable=redefined-builtin
import pygame_gui
import pygame
# import all screens for initialization (Note - must be done after pygame_gui manager is created)
from scripts.screens.all_screens import start_screen # pylint: disable=ungrouped-imports
# P Y G A M E
clock = pygame.time.Clock()
pygame.display.set_icon(pygame.image.load('resources/images/icon.png'))
# LOAD cats & clan
clan_list = game.read_clans()
if clan_list:
game.switches['clan_list'] = clan_list
try:
load_cats()
version_info = clan_class.load_clan()
version_convert(version_info)
except Exception as e:
logging.exception("File failed to load")
if not game.switches['error_message']:
game.switches[
'error_message'] = 'There was an error loading the cats file!'
game.switches['traceback'] = e
# LOAD settings
sprites.load_scars()
start_screen.screen_switches()
if game.settings['fullscreen']:
version_number = pygame_gui.elements.UILabel(
pygame.Rect((1500, 1350), (-1, -1)), get_version_info().version_number[0:8],
object_id=get_text_box_theme())
# Adjust position
version_number.set_position(
(1600 - version_number.get_relative_rect()[2] - 8,
1400 - version_number.get_relative_rect()[3]))
else:
version_number = pygame_gui.elements.UILabel(
pygame.Rect((700, 650), (-1, -1)), get_version_info().version_number[0:8],
object_id=get_text_box_theme())
# Adjust position
version_number.set_position(
(800 - version_number.get_relative_rect()[2] - 8,
700 - version_number.get_relative_rect()[3]))
if get_version_info().is_source_build or get_version_info().is_dev():
dev_watermark = pygame_gui.elements.UILabel(
scale(pygame.Rect((1050, 1321), (600, 100))),
"Dev Build:",
object_id="#dev_watermark"
)
game.rpc = _DiscordRPC("1076277970060185701", daemon=True)
game.rpc.start()
game.rpc.start_rpc.set()
cursor_img = pygame.image.load('resources/images/cursor.png').convert_alpha()
cursor = pygame.cursors.Cursor((9,0), cursor_img)
disabled_cursor = pygame.cursors.Cursor(pygame.SYSTEM_CURSOR_ARROW)
while True:
time_delta = clock.tick(30) / 1000.0
if game.switches['cur_screen'] not in ['start screen']:
if game.settings['dark mode']:
screen.fill((57, 50, 36))
else:
screen.fill((206, 194, 168))
if game.settings['custom cursor']:
if pygame.mouse.get_cursor() == disabled_cursor:
pygame.mouse.set_cursor(cursor)
elif pygame.mouse.get_cursor() == cursor:
pygame.mouse.set_cursor(disabled_cursor)
# Draw screens
# This occurs before events are handled to stop pygame_gui buttons from blinking.
game.all_screens[game.current_screen].on_use()
# EVENTS
for event in pygame.event.get():
game.all_screens[game.current_screen].handle_event(event)
if event.type == pygame.QUIT:
# Dont display if on the start screen or there is no clan.
if (game.switches['cur_screen'] in ['start screen',
'switch clan screen',
'settings screen',
'info screen',
'make clan screen']
or not game.clan):
quit(savesettings=False)
else:
SaveCheck(game.switches['cur_screen'], False, None)
# MOUSE CLICK
if event.type == pygame.MOUSEBUTTONDOWN:
game.clicked = True
# F2 turns toggles visual debug mode for pygame_gui, allowed for easier bug fixes.
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_F2:
if not MANAGER.visual_debug_active:
MANAGER.set_visual_debug_mode(True)
else:
MANAGER.set_visual_debug_mode(False)
MANAGER.process_events(event)
MANAGER.update(time_delta)
# update
game.update_game()
if game.switch_screens:
game.all_screens[game.last_screen_forupdate].exit_screen()
game.all_screens[game.current_screen].screen_switches()
game.switch_screens = False
# END FRAME
MANAGER.draw_ui(screen)
pygame.display.update()