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