· 6 years ago · Apr 18, 2020, 12:04 PM
1# Fixed Loop Error for F7, reworked GetAccounts Function
2
3import configparser
4import operator
5import os
6import sys
7import time
8import webbrowser
9from datetime import datetime, timedelta
10
11import pushbullet
12import pyperclip
13import pytesseract
14import requests
15import win32api
16import win32con
17import win32gui
18from PIL import ImageGrab, Image
19from playsound import playsound
20
21
22def Avg(lst: list):
23 if not lst:
24 return 0
25 return sum(lst) / len(lst)
26
27
28# noinspection PyShadowingNames,PyUnusedLocal
29def enum_cb(hwnd, results):
30 winlist.append((hwnd, win32gui.GetWindowText(hwnd)))
31
32
33# noinspection PyShadowingNames
34def write(message, add_time: bool = True, push: int = 0, push_now: bool = False, output: bool = True, overwrite: str = '0'):
35 if output:
36 message = str(message)
37 if add_time:
38 message = datetime.now().strftime('%H:%M:%S') + ': ' + message
39 overwrite_log = open(appdata_path + '\\overwrite_log.txt', 'rb+')
40 splits = b''.join(overwrite_log.readlines()).split(b'**')
41 last_key = splits[0]
42 last_string = splits[1].strip(b'\n\r')
43 last_end = splits[-1]
44
45 if overwrite != '0':
46 ending = console_window['suffix']
47 if last_key == overwrite.encode():
48 if console_window['isatty']:
49 print(' ' * len(last_string.decode()), end=ending)
50 message = console_window['prefix'] + message
51 else:
52 if last_end != b'\n':
53 message = '\n' + message
54 else:
55 ending = '\n'
56 if last_end != b'\n':
57 message = '\n' + message
58
59 overwrite_log.seek(0)
60 overwrite_log.truncate()
61 overwrite_log.write((overwrite + '**' + message + '**' + ending).encode())
62 overwrite_log.close()
63 print(message, end=ending)
64
65 if push >= 3:
66 global note
67 if message:
68 note = note + str(message) + '\n'
69 if push_now:
70 device.push_note('CSGO AUTO ACCEPT', note)
71 note = ''
72
73
74# noinspection PyShadowingNames
75def click(x: int, y: int):
76 win32api.SetCursorPos((x, y))
77 win32api.mouse_event(win32con.MOUSEEVENTF_LEFTDOWN, x, y, 0, 0)
78 win32api.mouse_event(win32con.MOUSEEVENTF_LEFTUP, x, y, 0, 0)
79
80
81# noinspection PyShadowingNames
82def relate_list(l_org, compare_list, relate: operator = operator.le):
83 if not l_org:
84 return False
85 truth_list = []
86 for list_part in compare_list:
87 partial_truth = []
88 for i, val in enumerate(list_part):
89 partial_truth.append(relate(l_org[i], val))
90 truth_list.append(all(partial_truth))
91 l_org = l_org[len(list_part):]
92 return any(truth_list)
93
94
95# noinspection PyShadowingNames
96def color_average(image: Image, compare_list: list):
97 average = []
98 r, g, b = [], [], []
99 data = image.getdata()
100 for i in data:
101 r.append(i[0])
102 g.append(i[1])
103 b.append(i[2])
104
105 rgb = [Avg(r), Avg(g), Avg(b)] * len(compare_list)
106 for part in compare_list:
107 for i, val in enumerate(part):
108 average.append(val - rgb[i])
109 average = list(map(abs, average))
110 return average
111
112
113# noinspection PyShadowingNames
114def getScreenShot(window_id: int, area: tuple = (0, 0, 0, 0)):
115 area = list(area)
116 win32gui.ShowWindow(window_id, win32con.SW_MAXIMIZE)
117 scaled_area = [screen_width / 2560, screen_height / 1440]
118 scaled_area = 2 * scaled_area
119 for i, _ in enumerate(area[-2:], start=len(area) - 2):
120 area[i] += 1
121 for i, val in enumerate(area, start=0):
122 scaled_area[i] = scaled_area[i] * val
123 scaled_area = list(map(int, scaled_area))
124 image = ImageGrab.grab(scaled_area)
125 return image
126
127
128# noinspection PyShadowingNames
129def getAccountsFromCfg():
130 steam_ids = ''
131 for i in config.sections():
132 if i.startswith('Account'):
133 steam_id = config.get(i, 'Steam ID')
134 auth_code = config.get(i, 'Authentication Code')
135 match_token = config.get(i, 'Match Token')
136 steam_ids += steam_id + ','
137 accounts.append({'steam_id': steam_id, 'auth_code': auth_code, 'match_token': match_token})
138
139 steam_ids = steam_ids.lstrip(',').rstrip(',')
140 profiles = requests.get('http://api.steampowered.com/ISteamUser/GetPlayerSummaries/v0002/?key=' + cfg['steam_api_key'] + '&steamids=' + steam_ids).json()['response']['players']
141 name_list = [online_data['personaname'] for local_acc in accounts for online_data in profiles if online_data['steamid'] == local_acc['steam_id']]
142 for num, val in enumerate(accounts):
143 val['name'] = name_list[num]
144
145
146# noinspection PyShadowingNames
147def getOldSharecodes(num: int = -1):
148 if num >= 0:
149 return []
150 try:
151 last_game = open(appdata_path+'last_game_' + accounts[current_account]['steam_id'] + '.txt', 'r')
152 games = last_game.readlines()
153 last_game.close()
154 except FileNotFoundError:
155 last_game = open(appdata_path+'last_game_' + accounts[current_account]['steam_id'] + '.txt', 'w')
156 last_game.write(accounts[current_account]['match_token'] + '\n')
157 games = [accounts[current_account]['match_token']]
158 last_game.close()
159 last_game = open(appdata_path+'last_game_' + accounts[current_account]['steam_id'] + '.txt', 'w')
160 games = games[-200:]
161 for i, val in enumerate(games):
162 games[i] = 'CSGO' + val.strip('\n').split('CSGO')[1]
163 last_game.write(games[i] + '\n')
164 last_game.close()
165 return games[num:]
166
167
168# noinspection PyShadowingNames
169def getNewCSGOSharecodes(game_id: str):
170 sharecodes = []
171 next_code = game_id
172 last_game = open(appdata_path+'last_game_' + accounts[current_account]['steam_id'] + '.txt', 'a')
173 while next_code != 'n/a':
174 steam_url = 'https://api.steampowered.com/ICSGOPlayers_730/GetNextMatchSharingCode/v1?key=' + cfg['steam_api_key'] + '&steamid=' + accounts[current_account]['steam_id'] + '&steamidkey=' + accounts[current_account][
175 'auth_code'] + '&knowncode=' + game_id
176 try:
177 next_code = (requests.get(steam_url).json()['result']['nextcode'])
178 except KeyError:
179 write('WRONG Match Token, Authentication Code or Steam ID ')
180 return [game_id]
181
182 if next_code:
183 if next_code != 'n/a':
184 sharecodes.append(next_code)
185 game_id = next_code
186 last_game.write(next_code + '\n')
187 if sharecodes:
188 return sharecodes
189 else:
190 return [game_id]
191
192
193def getAllQueuedGames():
194 num = -1
195 getNewCSGOSharecodes(getOldSharecodes()[0])
196 sharecode = getOldSharecodes()
197 while True:
198 response = requests.post('https://csgostats.gg/match/upload/ajax', data={'sharecode': sharecode, 'index': '1'})
199 if response.json()['status'] != 'complete':
200 num -= 1
201 try:
202 sharecode = getOldSharecodes(num)[0]
203 except IndexError:
204 return num+1
205 else:
206 return num+1
207
208
209# noinspection PyShadowingNames
210def UpdateCSGOstats(sharecodes: list, num_completed: int = 1):
211 completed_games, not_completed_games, = [], []
212 for val in sharecodes:
213 response = requests.post('https://csgostats.gg/match/upload/ajax', data={'sharecode': val, 'index': '1'})
214 if response.json()['status'] == 'complete':
215 completed_games.append(response.json())
216 else:
217 not_completed_games.append(response.json())
218
219 queued_games = [game['data']['queue_pos'] for game in not_completed_games if game['status'] != 'error']
220 global retrying_games, queue_difference, time_table
221 current_queue_difference = Avg([last_game[1] - game['data']['queue_pos'] for game in not_completed_games for last_game in retrying_games if last_game[0] == game['data']['sharecode']])
222 if current_queue_difference:
223 queue_difference.append(current_queue_difference / ((time.time() - time_table['error_check_time']) / 60))
224 queue_difference = queue_difference[-10:]
225 time_table['error_check_time'] = time.time()
226 retrying_games = []
227
228 if queued_games:
229 if queued_games[0] < cfg['max_queue_position']:
230 retrying_games = [(str(game['data']['sharecode']), int(game['data']['queue_pos'])) for game in not_completed_games if game['status'] != 'error']
231 temp_string = ''
232 for i, val in enumerate(queued_games):
233 temp_string += '#' + str(i + 1) + ': in Queue #' + str(val) + '. - '
234 temp_string += str(round(Avg(queue_difference), 1)) + ' matches/min'
235 write(temp_string, add_time=False, overwrite='4')
236
237 if len(not_completed_games) - len(queued_games) > 0:
238 write('An error occurred in %s game[s].' % (len(not_completed_games) - len(queued_games)), add_time=False)
239 retrying_games.append([(str(game['data']['sharecode']), 0) for game in not_completed_games if game['status'] == 'error'])
240
241 if completed_games:
242 for i in completed_games[num_completed * - 1:]:
243 sharecode = i['data']['sharecode']
244 game_url = i['data']['url']
245 info = ' '.join(i['data']['msg'].replace('-', '').replace('<br />', '. ').split('<')[0].rstrip(' ').split())
246 write('Sharecode: %s' % sharecode, add_time=False, push=push_urgency)
247 write('URL: %s' % game_url, add_time=False, push=push_urgency)
248 write('Status: %s.' % info, add_time=False, push=push_urgency)
249 pyperclip.copy(game_url)
250 write(None, add_time=False, push=push_urgency, push_now=True, output=False)
251
252
253# noinspection PyShadowingNames,PyUnusedLocal
254def Image_to_Text(image: Image, size: tuple, white_threshold: tuple, arg: str = ''):
255 image_data = image.getdata()
256 pixel_map, image_text = [], ''
257 for y in range(size[1]):
258 for x in range(size[0]):
259 if relate_list(image_data[y * size[0] + x], [white_threshold], relate=operator.ge):
260 pixel_map.append((0, 0, 0))
261 else:
262 pixel_map.append((255, 255, 255))
263 temp_image = Image.new('RGB', (size[0], size[1]))
264 temp_image.putdata(pixel_map)
265 try:
266 image_text = pytesseract.image_to_string(temp_image, timeout=0.3, config=arg)
267 except RuntimeError as timeout_error:
268 pass
269 if image_text:
270 image_text = ' '.join(image_text.replace(': ', ':').split())
271 global truth_table
272 if truth_table['debugging']:
273 image.save(str(cfg['debug_path']) + '\\' + datetime.now().strftime('%H-%M-%S') + '_' + image_text.replace(':', '-') + '.png', format='PNG')
274 temp_image.save(str(cfg['debug_path']) + '\\' + datetime.now().strftime('%H-%M-%S') + '_' + image_text.replace(':', '-') + '_temp.png', format='PNG')
275 return image_text
276 else:
277 return False
278
279
280def getCfgData():
281 try:
282 get_cfg = {'activate_script': int(config.get('HotKeys', 'Activate Script'), 16), 'activate_push_notification': int(config.get('HotKeys', 'Activate Push Notification'), 16),
283 'info_newest_match': int(config.get('HotKeys', 'Get Info on newest Match'), 16), 'info_multiple_matches': int(config.get('HotKeys', 'Get Info on multiple Matches'), 16),
284 'open_live_tab': int(config.get('HotKeys', 'Live Tab Key'), 16), 'switch_accounts': int(config.get('HotKeys', 'Switch accounts for csgostats.gg'), 16),
285 'end_script': int(config.get('HotKeys', 'End Script'), 16),
286 'screenshot_interval': config.getint('Screenshot', 'Interval'), 'debug_path': config.get('Screenshot', 'Debug Path'), 'steam_api_key': config.get('csgostats.gg', 'API Key'),
287 'last_x_matches': config.getint('csgostats.gg', 'Number of Requests'),
288 'completed_matches': config.getint('csgostats.gg', 'Completed Matches'), 'max_queue_position': config.getint('csgostats.gg', 'Auto-Retrying for queue position below'),
289 'auto_retry_interval': config.getint('csgostats.gg', 'Auto-Retrying-Interval'), 'pushbullet_device_name': config.get('Pushbullet', 'Device Name'), 'pushbullet_api_key': config.get('Pushbullet', 'API Key'),
290 'tesseract_path': config.get('Warmup', 'Tesseract Path'), 'warmup_test_interval': config.getint('Warmup', 'Test Interval'), 'warmup_push_interval': config.get('Warmup', 'Push Interval'),
291 'warmup_no_text_limit': config.getint('Warmup', 'No Text Limit')}
292 return get_cfg
293 # 'imgur_id': config.get('Imgur', 'Client ID'), 'imgur_secret': config.get('Imgur', 'Client Secret'), 'stop_warmup_ocr': int(config.get('HotKeys', 'Stop Warmup OCR'), 16),
294 except (configparser.NoOptionError, configparser.NoSectionError, ValueError):
295 write('ERROR IN CONFIG')
296 exit('CHECK FOR NEW CONFIG')
297
298
299# OVERWRITE SETUP
300appdata_path = os.getenv('APPDATA') + '\\CSGO AUTO ACCEPT\\'
301try:
302 os.mkdir(appdata_path)
303except FileExistsError:
304 pass
305overwrite_log = open(appdata_path+'\\overwrite_log.txt', 'wb')
306overwrite_log.write('0**\n'.encode())
307overwrite_log.close()
308console_window = {}
309if not sys.stdout.isatty():
310 console_window = {'prefix': '\r', 'suffix': '', 'isatty': False}
311else:
312 console_window = {'prefix': '', 'suffix': '\r', 'isatty': True}
313
314
315# CONFIG HANDLING
316config = configparser.ConfigParser()
317config.read('config.ini')
318cfg = getCfgData()
319device = 0
320
321# ACCOUNT HANDLING, GETTING ACCOUNT NAME
322accounts, current_account = [], 0
323getAccountsFromCfg()
324
325# INITIALIZATION FOR getScreenShot
326screen_width, screen_height = win32api.GetSystemMetrics(0), win32api.GetSystemMetrics(1)
327toplist, winlist = [], []
328hwnd = 0
329# BOOLEAN, TIME INITIALIZATION
330truth_table = {'test_for_live_game': False, 'test_for_success': False, 'test_for_warmup': False, 'first_ocr': True, 'testing': False, 'debugging': False, 'first_push': True}
331time_table = {'screenshot_time': time.time(), 'error_check_time': time.time(), 'warmup_test_timer': time.time(), 'time_searching': time.time()}
332
333# csgostats.gg VAR
334retrying_games, queue_difference = [], []
335
336# WARMUP DETECTION SETUP
337pytesseract.pytesseract.tesseract_cmd = cfg['tesseract_path']
338push_times, no_text_found, push_counter = [], 0, 0
339for i in cfg['warmup_push_interval'].split(','):
340 push_times.append(int(i))
341push_times.sort(reverse=True)
342join_warmup_time = push_times[0] + 1
343
344# PUSHBULLET VAR
345note = ''
346push_urgency = 0
347
348write('READY')
349write('Current account is: %s\n' % accounts[current_account]['name'], add_time=False)
350
351while True:
352 if win32api.GetAsyncKeyState(cfg['activate_script']) & 1: # F9 (ACTIVATE / DEACTIVATE SCRIPT)
353 truth_table['test_for_live_game'] = not truth_table['test_for_live_game']
354 write('TESTING: %s' % truth_table['test_for_live_game'], overwrite='1')
355 if truth_table['test_for_live_game']:
356 playsound('sounds/activated_2.mp3')
357 time_table['time_searching'] = time.time()
358 else:
359 playsound('sounds/deactivated.mp3')
360
361 if win32api.GetAsyncKeyState(cfg['activate_push_notification']) & 1: # F8 (ACTIVATE / DEACTIVATE PUSH NOTIFICATION)
362 if not device:
363 try:
364 device = pushbullet.PushBullet(cfg['pushbullet_api_key']).get_device(cfg['pushbullet_device_name'])
365 except (pushbullet.errors.PushbulletError, pushbullet.errors.InvalidKeyError):
366 write('Pushbullet is wrongly configured.\nWrong API Key or DeviceName in config.ini')
367 else:
368 push_urgency += 1
369 if push_urgency > 3:
370 push_urgency = 0
371 push_info = ['not active', 'only if accepted', 'all game status related information', 'all information (game status/csgostats.gg information)']
372 write('Pushing: %s' % push_info[push_urgency], overwrite='2')
373
374 if win32api.GetAsyncKeyState(cfg['info_newest_match']) & 1: # F7 Key (UPLOAD NEWEST MATCH)
375 write('Uploading / Getting status on newest match')
376 queue_difference = []
377 sharecodes = [i[0] for i in retrying_games] + getOldSharecodes(getAllQueuedGames())
378 sharecodes = sorted(set(sharecodes), key=lambda x: sharecodes.index(x))
379 if not sharecodes:
380 sharecodes = getOldSharecodes()
381 UpdateCSGOstats(sharecodes, num_completed=len(sharecodes))
382
383 if win32api.GetAsyncKeyState(cfg['info_multiple_matches']) & 1: # F6 Key (GET INFO ON LAST X MATCHES)
384 write('Getting Info from last %s matches' % cfg['last_x_matches'])
385 queue_difference = []
386 getNewCSGOSharecodes(getOldSharecodes()[0])
387 UpdateCSGOstats(getOldSharecodes(num=cfg['last_x_matches'] * -1), num_completed=cfg['completed_matches'])
388
389 if win32api.GetAsyncKeyState(cfg['open_live_tab']) & 1: # F13 Key (OPEN WEB BROWSER ON LIVE GAME TAB)
390 win32gui.ShowWindow(hwnd, win32con.SW_MAXIMIZE)
391 webbrowser.open_new_tab('https://csgostats.gg/player/' + accounts[current_account]['steam_id'] + '#/live')
392 write('new tab opened', add_time=False)
393 time.sleep(0.5)
394 win32gui.ShowWindow(hwnd, win32con.SW_MAXIMIZE)
395
396 if win32api.GetAsyncKeyState(cfg['switch_accounts']) & 1: # F15 (SWITCH ACCOUNTS)
397 current_account += 1
398 if current_account > len(accounts) - 1:
399 current_account = 0
400 write('current account is: %s' % accounts[current_account]['name'], add_time=False, overwrite='3')
401
402 if win32api.GetAsyncKeyState(cfg['end_script']) & 1: # POS1 (END SCRIPT)
403 write('Exiting Script')
404 break
405
406 if retrying_games:
407 if time.time() - time_table['error_check_time'] > cfg['auto_retry_interval']:
408 temp_list = [i[0] for i in retrying_games]
409 UpdateCSGOstats(temp_list, num_completed=len(temp_list))
410
411 winlist = []
412 win32gui.EnumWindows(enum_cb, toplist)
413 csgo = [(hwnd, title) for hwnd, title in winlist if 'counter-strike: global offensive' in title.lower()]
414
415 # ONLY CONTINUING IF CSGO IS RUNNING
416 if not csgo:
417 continue
418 hwnd = csgo[0][0]
419
420 # TESTING HERE
421 if win32api.GetAsyncKeyState(0x6F) & 1: # UNBOUND, TEST CODE
422 # truth_table['testing'] = not truth_table['testing']
423 truth_table['debugging'] = not truth_table['debugging']
424 # truth_table['test_for_warmup'] = not truth_table['test_for_warmup']
425 # time_table['warmup_test_timer'] = time.time() + 2
426 write('DEBUGGING: %s\n' % truth_table['debugging'])
427
428 if truth_table['testing']:
429 # time_table['screenshot_time'] = time.time()
430 pass
431 # print('Took: %s ' % str(timedelta(milliseconds=int(time.time(*1000 - time_table['screenshot_time']*1000))))
432 # TESTING ENDS HERE
433
434 if truth_table['test_for_live_game']:
435 if time.time() - time_table['screenshot_time'] < cfg['screenshot_interval']:
436 continue
437 time_table['screenshot_time'] = time.time()
438 img = getScreenShot(hwnd, (1265, 760, 1295, 785))
439 if not img:
440 continue
441 accept_avg = color_average(img, [(76, 176, 80), (89, 203, 94)])
442 if relate_list(accept_avg, [(2, 2, 2), (2, 2, 2)]):
443 write('Trying to Accept', push=push_urgency + 1)
444
445 truth_table['test_for_success'] = True
446 truth_table['test_for_live_game'] = False
447 accept_avg = []
448
449 for _ in range(5):
450 click(int(screen_width / 2), int(screen_height / 1.78))
451 pass
452
453 write('Trying to catch a loading map')
454 playsound('sounds/accept_found.mp3')
455 time_table['screenshot_time'] = time.time()
456
457 if truth_table['test_for_success']:
458 if time.time() - time_table['screenshot_time'] < 40:
459 img = getScreenShot(hwnd, (2435, 65, 2555, 100))
460 not_searching_avg = color_average(img, [(6, 10, 10)])
461 searching_avg = color_average(img, [(6, 163, 97), (4, 63, 35)])
462
463 not_searching = relate_list(not_searching_avg, [(2, 5, 5)])
464 searching = relate_list(searching_avg, [(2.7, 55, 35), (1, 50, 35)])
465
466 img = getScreenShot(hwnd, (467, 1409, 1300, 1417))
467 success_avg = color_average(img, [(21, 123, 169)])
468 success = relate_list(success_avg, [(1, 8, 7)])
469
470 if success:
471 write('Took %s since pressing accept.' % str(timedelta(seconds=int(time.time() - time_table['screenshot_time']))), add_time=False, push=push_urgency + 1)
472 write('Took %s since trying to find a game.' % str(timedelta(seconds=int(time.time() - time_table['time_searching']))), add_time=False, push=push_urgency + 1)
473 write('Game should have started', push=push_urgency + 2, push_now=True)
474 truth_table['test_for_success'] = False
475 truth_table['test_for_warmup'] = True
476 playsound('sounds/done_testing.mp3')
477 time_table['warmup_test_timer'] = time.time() + 5
478
479 if any([searching, not_searching]):
480 write('Took: %s ' % str(timedelta(seconds=int(time.time() - time_table['screenshot_time']))), add_time=False, push=push_urgency + 1)
481 write('Game doesnt seem to have started. Continuing to search for accept Button!', push=push_urgency + 1, push_now=True)
482 playsound('sounds/back_to_testing.mp3')
483 truth_table['test_for_success'] = False
484 truth_table['test_for_live_game'] = True
485
486 else:
487 write('40 Seconds after accept, did not find loading map nor searching queue')
488 truth_table['test_for_success'] = False
489 print(success_avg)
490 print(searching_avg)
491 print(not_searching_avg)
492 playsound('sounds/fail.mp3')
493 img.save(os.path.expanduser('~') + '\\Unknown Error.png')
494
495 if truth_table['test_for_warmup']:
496 for i in range(112, 113): # 136
497 win32api.GetAsyncKeyState(i) & 1
498 while True:
499 keys = []
500 for i in range(112, 113):
501 keys.append(win32api.GetAsyncKeyState(i) & 1)
502 if any(keys):
503 write('Break from warmup-loop')
504 truth_table['test_for_warmup'] = False
505 truth_table['first_ocr'] = True
506 truth_table['first_push'] = True
507 break
508
509 if time.time() - time_table['warmup_test_timer'] >= cfg['warmup_test_interval']:
510 img = getScreenShot(hwnd, (1036, 425, 1525, 456)) # 'WAITING FOR PLAYERS X:XX'
511 img_text = Image_to_Text(img, img.size, (225, 225, 225), arg='--psm 6')
512 time_table['warmup_test_timer'] = time.time()
513 if img_text:
514 time_left = img_text.split()[-1].split(':')
515 # write(img_text, add_time=False)
516 try:
517 time_left = int(time_left[0]) * 60 + int(time_left[1])
518 if truth_table['first_ocr']:
519 join_warmup_time = time_left
520 time_table['screenshot_time'] = time.time()
521 truth_table['first_ocr'] = False
522
523 except ValueError:
524 time_left = push_times[0] + 1
525
526 time_left_data = timedelta(seconds=int(time.time() - time_table['screenshot_time'])), time.strftime('%H:%M:%S', time.gmtime(abs((join_warmup_time - time_left) - (time.time() - time_table['screenshot_time'])))), img_text
527 write('Time since start: %s - Time Difference: %s - Time left: %s' % (time_left_data[0], time_left_data[1], time_left_data[2]), add_time=False, overwrite='1')
528 if no_text_found > 0:
529 no_text_found -= 1
530
531 if time_left <= push_times[push_counter]:
532 push_counter += 1
533 write('Time since start: %s\nTime Difference: %s\nTime left: %s' % (time_left_data[0], time_left_data[1], time_left_data[2]), push=push_urgency + 1, output=False, push_now=True)
534
535 if truth_table['first_push']:
536 if abs((join_warmup_time - time_left) - (time.time() - time_table['screenshot_time'])) >= 5:
537 truth_table['first_push'] = False
538 write('Match should start in ' + str(time_left) + 'seconds, All players have connected', push=push_urgency + 2, push_now=True)
539
540 else:
541 no_text_found += 1
542
543 if push_counter >= len(push_times):
544 push_counter = 0
545 no_text_found = 0
546 truth_table['test_for_warmup'] = False
547 truth_table['first_ocr'] = True
548 truth_table['first_push'] = True
549 write('Warmup should be over in less then %s seconds!' % push_times[-1], push=push_urgency + 2, push_now=True)
550 break
551
552 if no_text_found >= cfg['warmup_no_text_limit']:
553 push_counter = 0
554 no_text_found = 0
555 truth_table['test_for_warmup'] = False
556 truth_table['first_ocr'] = True
557 truth_table['first_push'] = True
558 write('Did not find any warmup text.', push=push_urgency + 2, push_now=True)
559 break
560
561exit('ENDED BY USER')