· 6 years ago · Apr 25, 2020, 02:34 PM
1import configparser
2import operator
3import os
4import re
5import sys
6import time
7import webbrowser
8import winreg
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
33def mute_csgo(lvl: int):
34 os.system(mute_csgo_path + str(lvl))
35
36
37
38# noinspection PyShadowingNames
39def write(message, add_time: bool = True, push: int = 0, push_now: bool = False, output: bool = True, overwrite: str = '0'):
40 if output:
41 message = str(message)
42 if add_time:
43 message = datetime.now().strftime('%H:%M:%S') + ': ' + message
44 global last_printed_line
45 splits = last_printed_line.split(b'**')
46 last_key = splits[0]
47 last_string = splits[1].strip(b'\n\r')
48 last_end = splits[-1]
49 if overwrite != '0':
50 ending = console_window['suffix']
51 if last_key == overwrite.encode():
52 if console_window['isatty']:
53 print(' ' * len(last_string.decode()), end=ending)
54 message = console_window['prefix'] + message
55 else:
56 if last_end != b'\n':
57 message = '\n' + message
58 else:
59 ending = '\n'
60 if last_end != b'\n':
61 message = '\n' + message
62
63 last_printed_line = (overwrite + '**' + message + '**' + ending).encode()
64 print(message, end=ending)
65
66 if push >= 3:
67 global note
68 if message:
69 note = note + str(message.strip('\n\r')) + '\n'
70 if push_now:
71 device.push_note('CSGO AUTO ACCEPT', note)
72 note = ''
73
74
75# noinspection PyShadowingNames
76def click(x: int, y: int):
77 win32api.SetCursorPos((x, y))
78 win32api.mouse_event(win32con.MOUSEEVENTF_LEFTDOWN, x, y, 0, 0)
79 win32api.mouse_event(win32con.MOUSEEVENTF_LEFTUP, x, y, 0, 0)
80
81
82# noinspection PyShadowingNames
83def relate_list(l_org, compare_list, relate: operator = operator.le):
84 if not l_org:
85 return False
86 truth_list = []
87 for list_part in compare_list:
88 partial_truth = []
89 for i, val in enumerate(list_part):
90 partial_truth.append(relate(l_org[i], val))
91 truth_list.append(all(partial_truth))
92 l_org = l_org[len(list_part):]
93 return any(truth_list)
94
95
96# noinspection PyShadowingNames
97def color_average(image: Image, compare_list: list):
98 average = []
99 r, g, b = [], [], []
100 data = image.getdata()
101 for i in data:
102 r.append(i[0])
103 g.append(i[1])
104 b.append(i[2])
105
106 rgb = [Avg(r), Avg(g), Avg(b)] * len(compare_list)
107 for part in compare_list:
108 for i, val in enumerate(part):
109 average.append(val - rgb[i])
110 average = list(map(abs, average))
111 return average
112
113
114# noinspection PyShadowingNames
115def getScreenShot(window_id: int, area: tuple = (0, 0, 0, 0)):
116 area = list(area)
117 win32gui.ShowWindow(window_id, win32con.SW_MAXIMIZE)
118 scaled_area = [screen_width / 2560, screen_height / 1440]
119 scaled_area = 2 * scaled_area
120 for i, _ in enumerate(area[-2:], start=len(area) - 2):
121 area[i] += 1
122 for i, val in enumerate(area, start=0):
123 scaled_area[i] = scaled_area[i] * val
124 scaled_area = list(map(int, scaled_area))
125 # time.sleep(0.001)
126 image = ImageGrab.grab(scaled_area)
127 return image
128
129
130# noinspection PyShadowingNames
131def getAccountsFromCfg():
132 steam_ids = ''
133 global accounts
134 for i in config.sections():
135 if i.startswith('Account'):
136 steam_id = config.get(i, 'Steam ID')
137 steam_id_3 = str(int(steam_id) - 76561197960265728)
138 auth_code = config.get(i, 'Authentication Code')
139 match_token = config.get(i, 'Match Token')
140 steam_ids += steam_id + ','
141 accounts.append({'steam_id': steam_id, 'steam_id_3': steam_id_3, 'auth_code': auth_code, 'match_token': match_token})
142
143 steam_ids = steam_ids.lstrip(',').rstrip(',')
144 profiles = requests.get('http://api.steampowered.com/ISteamUser/GetPlayerSummaries/v0002/?key=' + cfg['steam_api_key'] + '&steamids=' + steam_ids).json()['response']['players']
145 name_list = [online_data['personaname'] for local_acc in accounts for online_data in profiles if online_data['steamid'] == local_acc['steam_id']]
146 for num, val in enumerate(accounts):
147 val['name'] = name_list[num]
148
149
150# noinspection PyShadowingNames
151def getCsgoPath(steam_id_3: str):
152 steam_reg_key = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, 'SOFTWARE\WOW6432Node\Valve\Steam')
153 steam_path = winreg.QueryValueEx(steam_reg_key, 'InstallPath')[0]
154 libraries = [steam_path + '\\steamapps']
155 with open(steam_path + '\\steamapps\\libraryfolders.vdf', 'r') as library_file:
156 library_data = library_file.readlines()
157 compare_str = re.compile('\\t"\d*"\\t\\t"')
158 libraries.extend([re.sub(compare_str, "", i.rstrip('"\n')) for i in library_data if bool(re.match(compare_str, i))])
159
160 csgo_path = [i for i in libraries if os.path.exists(i + '\\appmanifest_730.acf')][0] + '\\common\\Counter-Strike Global Offensive\\csgo\\'
161 if not csgo_path:
162 write('DID NOT FIND CSGO PATH', add_time=False)
163 exit('LORD PLZ HELP')
164
165 userdata_path = steam_path + '\\userdata\\' + steam_id_3 + '\\730\\local\\cfg\\'
166 with open(userdata_path + 'autoexec.cfg', 'a+') as autoexec:
167 autoexec.seek(0)
168 lines = autoexec.readlines()
169 if 'con_logfile "console_log.log"' not in [line.rstrip('\n') for line in lines]:
170 write('ADDED CONSOLE LOGGING OUTPUT TO "autoexec.cfg" FILE IN %s' % userdata_path, add_time=False)
171 write('YOU HAVE TO RESTART Counter-Strike FOR THE SCRIPT TO WORK', add_time=False)
172 autoexec.write('\ncon_logfile "console_log.log"\n')
173 if os.path.exists(csgo_path + '\\cfg\\autoexec.cfg'):
174 write('YOU HAVE TO DELETE THE "autoexec.cfg" in %s WITH AND MERGE IT WITH THE ONE IN %s' % (csgo_path + '\\cfg', userdata_path), add_time=False)
175 write('THE SCRIPT WONT WORK UNTIL THERE IS NO "autoexec.cfg" in %s' % csgo_path + '\\cfg', add_time=False)
176 exit()
177 return csgo_path
178
179
180# noinspection PyShadowingNames
181def getOldSharecodes(last_x: int = -1, from_x: str = ''):
182 if last_x >= 0:
183 return []
184 try:
185 last_game = open(appdata_path+'last_game_' + accounts[current_account]['steam_id'] + '.txt', 'r')
186 games = last_game.readlines()
187 last_game.close()
188 except FileNotFoundError:
189 last_game = open(appdata_path+'last_game_' + accounts[current_account]['steam_id'] + '.txt', 'w')
190 last_game.write(accounts[current_account]['match_token'] + '\n')
191 games = [accounts[current_account]['match_token']]
192 last_game.close()
193 last_game = open(appdata_path+'last_game_' + accounts[current_account]['steam_id'] + '.txt', 'w')
194 games = games[-200:]
195 for i, val in enumerate(games):
196 games[i] = 'CSGO' + val.strip('\n').split('CSGO')[1]
197 last_game.write(games[i] + '\n')
198 last_game.close()
199 if from_x:
200 try:
201 return games[(len(games) - games.index(from_x)) * -1:]
202 except ValueError:
203 return []
204 return games[last_x:]
205
206
207# noinspection PyShadowingNames
208def getNewCSGOSharecodes(game_id: str):
209 sharecodes = []
210 next_code = game_id
211 last_game = open(appdata_path+'last_game_' + accounts[current_account]['steam_id'] + '.txt', 'a')
212 while next_code != 'n/a':
213 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][
214 'auth_code'] + '&knowncode=' + game_id
215 try:
216 next_code = (requests.get(steam_url).json()['result']['nextcode'])
217 except KeyError:
218 write('WRONG Match Token, Authentication Code or Steam ID ')
219 return [{'sharecode': game_id, 'queue_pos': None}]
220
221 if next_code:
222 if next_code != 'n/a':
223 sharecodes.append(next_code)
224 game_id = next_code
225 last_game.write(next_code + '\n')
226 last_game.close()
227 return [{'sharecode': code, 'queue_pos': None} for code in sharecodes]
228
229
230# noinspection PyShadowingNames
231def UpdateCSGOstats(repeater=None, get_all_games=False):
232 all_games, completed_games, not_completed_games, = [], [], []
233
234 if repeater is None:
235 repeater = []
236 if repeater:
237 if get_all_games:
238 sharecodes = [getOldSharecodes(from_x=code['sharecode']) for code in repeater]
239 sharecodes = max(sharecodes, key=len)
240 else:
241 sharecodes = [code['sharecode'] for code in repeater]
242 all_games = [requests.post('https://csgostats.gg/match/upload/ajax', data={'sharecode': sharecode, 'index': '1'}).json() for sharecode in sharecodes]
243 else:
244 num = -1
245 sharecode = getOldSharecodes(num)[0]
246 while True:
247 response = requests.post('https://csgostats.gg/match/upload/ajax', data={'sharecode': sharecode, 'index': '1'})
248 all_games.append(response.json())
249 if response.json()['status'] != 'complete':
250 num -= 1
251 try:
252 sharecode = getOldSharecodes(num)[0]
253 except IndexError:
254 break
255 else:
256 break
257 temp_games = [{'sharecode': game['data']['sharecode']} for game in all_games if game['status'] != 'complete']
258 if temp_games and len(all_games) > 1:
259 all_games = all_games[:-1]
260
261 for game in all_games:
262 if game['status'] == 'complete':
263 completed_games.append(game)
264 else:
265 not_completed_games.append(game)
266
267 queued_games = [{'sharecode': game['data']['sharecode'], 'queue_pos': game['data']['queue_pos']} for game in not_completed_games if game['status'] != 'error']
268 corrupt_games = [{'sharecode': game['data']['sharecode'], 'queue_pos': None} for game in not_completed_games if game['status'] == 'error']
269
270 global queue_difference, time_table
271 if queued_games:
272 temp_string = ''
273 for i, val in enumerate(queued_games):
274 temp_string += '#' + str(i + 1) + ': in Queue #' + str(val['queue_pos']) + ' - '
275
276 if repeater:
277 current_queue_difference = Avg([last_game['queue_pos'] - game['queue_pos'] for game in queued_games for last_game in repeater if last_game['sharecode'] == game['sharecode'] and last_game['queue_pos'] is not None])
278 if current_queue_difference:
279 queue_difference.append(current_queue_difference / ((time.time() - time_table['time_since_retry']) / 60))
280 queue_difference = queue_difference[-10:]
281 matches_per_min = round(Avg(queue_difference), 1)
282 if matches_per_min != 0.0:
283 time_till_done = str(timedelta(seconds=int((queued_games[0]['queue_pos'] / matches_per_min) * 60)))
284 else:
285 time_till_done = '∞:∞:∞'
286 temp_string += str(matches_per_min) + ' matches/min - #1 done in ' + time_till_done
287 temp_string = temp_string.rstrip(' - ')
288 write(temp_string, add_time=False, overwrite='4')
289
290 time_table['time_since_retry'] = time.time()
291 repeater = [game for game in queued_games if game['queue_pos'] < cfg['max_queue_position']]
292 repeater.extend([game for game in corrupt_games])
293
294 if corrupt_games:
295 write('An error occurred in %s game[s].' % len(corrupt_games), overwrite='5')
296
297 if completed_games:
298 for i in completed_games:
299 sharecode = i['data']['sharecode']
300 game_url = i['data']['url']
301 info = ' '.join(i['data']['msg'].replace('-', '').replace('<br />', '. ').split('<')[0].rstrip(' ').split())
302 write('Sharecode: %s' % sharecode, add_time=False, push=push_urgency)
303 write('URL: %s' % game_url, add_time=False, push=push_urgency)
304 write('Status: %s.' % info, add_time=True, push=push_urgency)
305 pyperclip.copy(game_url)
306 write(None, add_time=False, push=push_urgency, push_now=True, output=False)
307 return repeater
308
309
310# noinspection PyShadowingNames,PyUnusedLocal
311def Image_to_Text(image: Image, size: tuple, white_threshold: tuple, arg: str = ''):
312 image_data = image.getdata()
313 pixel_map, image_text = [], ''
314 for y in range(size[1]):
315 for x in range(size[0]):
316 if relate_list(image_data[y * size[0] + x], [white_threshold], relate=operator.ge):
317 pixel_map.append((0, 0, 0))
318 else:
319 pixel_map.append((255, 255, 255))
320 temp_image = Image.new('RGB', (size[0], size[1]))
321 temp_image.putdata(pixel_map)
322 try:
323 image_text = pytesseract.image_to_string(temp_image, timeout=0.3, config=arg)
324 except RuntimeError:
325 # as timeout_error:
326 pass
327 if image_text:
328 image_text = ' '.join(image_text.replace(': ', ':').split())
329 global truth_table
330 if truth_table['debugging']:
331 image.save(str(cfg['debug_path']) + '\\' + datetime.now().strftime('%H-%M-%S') + '_' + image_text.replace(':', '-') + '.png', format='PNG')
332 temp_image.save(str(cfg['debug_path']) + '\\' + datetime.now().strftime('%H-%M-%S') + '_' + image_text.replace(':', '-') + '_temp.png', format='PNG')
333 return image_text
334 else:
335 return ''
336
337
338def getCfgData():
339 try:
340 get_cfg = {'activate_script': int(config.get('HotKeys', 'Activate Script'), 16), 'activate_push_notification': int(config.get('HotKeys', 'Activate Push Notification'), 16),
341 'info_newest_match': int(config.get('HotKeys', 'Get Info on newest Match'), 16), 'mute_csgo_toggle': int(config.get('HotKeys', 'Mute CSGO'), 16),
342 'open_live_tab': int(config.get('HotKeys', 'Live Tab Key'), 16), 'switch_accounts': int(config.get('HotKeys', 'Switch accounts for csgostats.gg'), 16),
343 'end_script': int(config.get('HotKeys', 'End Script'), 16), 'stop_warmup_ocr': config.get('HotKeys', 'Stop Warmup OCR'),
344 'screenshot_interval': float(config.get('Screenshot', 'Interval')), 'timeout_time': config.getint('Screenshot', 'Timeout Time'), 'debug_path': config.get('Screenshot', 'Debug Path'), 'steam_api_key': config.get('csgostats.gg', 'API Key'),
345 'max_queue_position': config.getint('csgostats.gg', 'Auto-Retrying for queue position below'),
346 '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'),
347 'tesseract_path': config.get('Warmup', 'Tesseract Path'), 'warmup_test_interval': config.getint('Warmup', 'Test Interval'), 'warmup_push_interval': config.get('Warmup', 'Push Interval'),
348 'warmup_no_text_limit': config.getint('Warmup', 'No Text Limit')}
349 return get_cfg
350 # '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), 'info_multiple_matches': int(config.get('HotKeys', 'Get Info on multiple Matches'), 16),
351 except (configparser.NoOptionError, configparser.NoSectionError, ValueError):
352 write('ERROR IN CONFIG')
353 exit('CHECK FOR NEW CONFIG')
354
355
356# OVERWRITE SETUP
357appdata_path = os.getenv('APPDATA') + '\\CSGO AUTO ACCEPT\\'
358try:
359 os.mkdir(appdata_path)
360except FileExistsError:
361 pass
362last_printed_line = b'0**\n'
363console_window = {}
364if not sys.stdout.isatty():
365 console_window = {'prefix': '\r', 'suffix': '', 'isatty': False}
366else:
367 console_window = {'prefix': '', 'suffix': '\r', 'isatty': True}
368
369# CONFIG HANDLING
370config = configparser.ConfigParser()
371config.read('config.ini')
372cfg = getCfgData()
373cfg['timeout_time'] = int(cfg['timeout_time'] / cfg['screenshot_interval'])
374cfg['stop_warmup_ocr'] = [int(i, 16) for i in cfg['stop_warmup_ocr'].split('-')]
375cfg['stop_warmup_ocr'][1] += 1
376device = 0
377
378# ACCOUNT HANDLING, GETTING ACCOUNT NAME, GETTING CSGO PATH, CHECKING AUTOEXEC
379accounts, current_account = [], 0
380getAccountsFromCfg()
381csgo_path = getCsgoPath(accounts[current_account]['steam_id_3'])
382match_server_ready = re.compile('^Server reservation check .* ready-up!$')
383match_reservation = 'Matchmaking reservation confirmed: '
384match_warmup_time = re.compile('\d+?:\d+')
385inverted_warmup_time = re.compile('[^\d:]')
386with open(csgo_path + 'console_log.log', 'w') as log:
387 log.write('')
388with open(cfg['debug_path'] + '\\console.log', 'w') as debug_log:
389 debug_log.write('')
390
391# INITIALIZATION FOR getScreenShot
392screen_width, screen_height = win32api.GetSystemMetrics(0), win32api.GetSystemMetrics(1)
393hwnd = 0
394toplist, csgo = [], []
395
396# BOOLEAN, TIME INITIALIZATION
397truth_table = {'test_for_accept_button': False, 'test_for_success': False, 'test_for_warmup': False, 'first_ocr': True, 'testing': False, 'debugging': False, 'first_push': True, 'test_for_server': False}
398time_table = {'screenshot_time': time.time(), 'time_since_retry': time.time(), 'warmup_test_timer': time.time(), 'time_searching': time.time(), 'not_searching_cc': time.time(), 'searching_cc': time.time()}
399test_for_accept_counter = 0
400
401# csgostats.gg VAR
402retryer = []
403
404# WARMUP DETECTION SETUP
405pytesseract.pytesseract.tesseract_cmd = cfg['tesseract_path']
406no_text_found, push_counter = 0, 0
407push_times = [int(i) for i in cfg['warmup_push_interval'].split(',')]
408push_times.sort(reverse=True)
409join_warmup_time = push_times[0] + 1
410
411# PUSHBULLET VAR
412note = ''
413push_urgency = 0
414
415# MUTE CSGO PATH
416mute_csgo_path = '"' + os.getcwd() + '\\sounds\\nircmdc.exe" muteappvolume csgo.exe '
417mute_csgo(0)
418
419write('READY')
420write('Current account is: %s\n' % accounts[current_account]['name'], add_time=False)
421
422
423while True:
424 if win32api.GetAsyncKeyState(cfg['activate_script']) & 1: # F9 (ACTIVATE / DEACTIVATE SCRIPT)
425 truth_table['test_for_server'] = not truth_table['test_for_server']
426 write('TESTING: %s' % truth_table['test_for_server'], overwrite='1')
427 if truth_table['test_for_server']:
428 playsound('sounds/activated_2.mp3')
429 time_table['time_searching'] = time.time()
430 mute_csgo(1)
431 else:
432 playsound('sounds/deactivated.mp3')
433 mute_csgo(0)
434
435 if win32api.GetAsyncKeyState(cfg['activate_push_notification']) & 1: # F8 (ACTIVATE / DEACTIVATE PUSH NOTIFICATION)
436 if not device:
437 try:
438 device = pushbullet.PushBullet(cfg['pushbullet_api_key']).get_device(cfg['pushbullet_device_name'])
439 except (pushbullet.errors.PushbulletError, pushbullet.errors.InvalidKeyError):
440 write('Pushbullet is wrongly configured.\nWrong API Key or DeviceName in config.ini')
441 if device:
442 push_urgency += 1
443 if push_urgency > 3:
444 push_urgency = 0
445 push_info = ['not active', 'only if accepted', 'all game status related information', 'all information (game status/csgostats.gg information)']
446 write('Pushing: %s' % push_info[push_urgency], overwrite='2')
447
448 if win32api.GetAsyncKeyState(cfg['info_newest_match']) & 1: # F7 Key (UPLOAD NEWEST MATCH)
449 write('Uploading / Getting status on newest match')
450 queue_difference = []
451 new_sharecodes = getNewCSGOSharecodes(getOldSharecodes(-1)[0])
452 for new_code in new_sharecodes:
453 retryer.append(new_code) if new_code['sharecode'] not in [old_code['sharecode'] for old_code in retryer] else retryer
454 retryer = UpdateCSGOstats(retryer, get_all_games=True)
455
456 if win32api.GetAsyncKeyState(cfg['open_live_tab']) & 1: # F13 Key (OPEN WEB BROWSER ON LIVE GAME TAB)
457 win32gui.ShowWindow(hwnd, win32con.SW_MAXIMIZE)
458 webbrowser.open_new_tab('https://csgostats.gg/player/' + accounts[current_account]['steam_id'] + '#/live')
459 write('new tab opened', add_time=False)
460 time.sleep(0.5)
461 win32gui.ShowWindow(hwnd, win32con.SW_MAXIMIZE)
462
463 if win32api.GetAsyncKeyState(cfg['switch_accounts']) & 1: # F15 (SWITCH ACCOUNTS)
464 current_account += 1
465 if current_account > len(accounts) - 1:
466 current_account = 0
467 getCsgoPath(accounts[current_account]['steam_id_3'])
468 write('current account is: %s' % accounts[current_account]['name'], add_time=False, overwrite='3')
469
470 if win32api.GetAsyncKeyState(cfg['mute_csgo_toggle']) & 1: # POS1 (END SCRIPT)
471 write("MUTE TOGGLED", add_time=False)
472 mute_csgo(2)
473
474 if win32api.GetAsyncKeyState(cfg['end_script']) & 1: # POS1 (END SCRIPT)
475 write('Exiting Script')
476 break
477
478 if retryer:
479 if time.time() - time_table['time_since_retry'] > cfg['auto_retry_interval']:
480 retryer = UpdateCSGOstats(retryer)
481 winlist = []
482 win32gui.EnumWindows(enum_cb, toplist)
483 csgo = [(hwnd, title) for hwnd, title in winlist if 'counter-strike: global offensive' in title.lower()]
484 if not csgo:
485 continue
486 hwnd = csgo[0][0]
487
488 # TESTING HERE
489 if win32api.GetAsyncKeyState(0x6F) & 1: # UNBOUND, TEST CODE
490 # truth_table['debugging'] = not truth_table['debugging']
491 truth_table['test_for_warmup'] = not truth_table['test_for_warmup']
492 write('DEBUGGING: %s\n' % truth_table['debugging'])
493
494 if truth_table['testing']:
495 # time_table['screenshot_time'] = time.time()
496 pass
497 # print('Took: %s ' % str(timedelta(milliseconds=int(time.time(*1000 - time_table['screenshot_time']*1000))))
498 # TESTING ENDS HERE
499
500 if truth_table['test_for_server']:
501 if time.time() - time_table['searching_cc'] > 0.2:
502 time_table['searching_cc'] = time.time()
503 else:
504 continue
505 with open(csgo_path + 'console_log.log', 'rb+') as log:
506 log_lines = log.readlines()
507 console_line = [line.decode('utf-8', 'ignore').encode("utf-8").rstrip(b'\n\r').decode() for line in log_lines]
508 log.seek(0)
509 log.truncate()
510 with open(cfg['debug_path'] + '\\console.log', 'ab') as debug_log:
511 [debug_log.write(i) for i in log_lines]
512 # server_ready = any([bool(re.match(match_server_ready, i)) for i in console_line])
513 server_ready = any(match_reservation in i for i in console_line)
514 if server_ready:
515 test_for_accept_counter = 0
516 write('Server found, starting to look for accept button')
517 truth_table['test_for_accept_button'] = True
518 # truth_table['test_for_server'] = False
519 playsound('sounds/server_found.mp3')
520 win32gui.ShowWindow(hwnd, win32con.SW_MAXIMIZE)
521 else:
522 if time.time() - time_table['not_searching_cc'] > 20:
523 time_table['not_searching_cc'] = time.time()
524 with open(csgo_path + 'console_log.log', 'w') as log:
525 log.write('')
526
527 if truth_table['test_for_accept_button']:
528 if time.time() - time_table['screenshot_time'] < cfg['screenshot_interval']:
529 continue
530 time_table['screenshot_time'] = time.time()
531 img = getScreenShot(hwnd, (1265, 760, 1295, 785))
532 if not img:
533 continue
534 accept_avg = color_average(img, [(76, 176, 80), (89, 203, 94)])
535 mute_csgo(0)
536 if relate_list(accept_avg, [(2, 2, 2), (2, 2, 2)]):
537 write('Trying to Accept', push=push_urgency + 1)
538
539 truth_table['test_for_success'] = True
540 truth_table['test_for_accept_button'] = False
541 truth_table['test_for_server'] = False
542 accept_avg = []
543
544 for _ in range(5):
545 click(int(screen_width / 2), int(screen_height / 1.78))
546 pass
547
548 write('Trying to catch a loading map')
549 playsound('sounds/accept_found.mp3')
550 time_table['screenshot_time'] = time.time()
551 test_for_accept_counter += 1
552 if test_for_accept_counter > cfg['timeout_time']:
553 write('NO ACCEPT BUTTON FOUND AFTER %s seconds.' % str(int(cfg['timeout_time']*cfg['screenshot_interval'])))
554 write('Continuing to look for ready server.')
555 mute_csgo(1)
556 playsound('sounds/back_to_testing.mp3')
557 truth_table['test_for_accept_button'] = False
558
559 if truth_table['test_for_success']:
560 if time.time() - time_table['screenshot_time'] < 40:
561 img = getScreenShot(hwnd, (2435, 65, 2555, 100))
562 not_searching_avg = color_average(img, [(6, 10, 10)])
563 searching_avg = color_average(img, [(6, 163, 97), (4, 63, 35)])
564
565 not_searching = relate_list(not_searching_avg, [(2, 5, 5)])
566 searching = relate_list(searching_avg, [(2.7, 55, 35), (1, 50, 35)])
567
568 img = getScreenShot(hwnd, (467, 1409, 1300, 1417))
569 success_avg = color_average(img, [(21, 123, 169)])
570 success = relate_list(success_avg, [(1, 8, 7)])
571
572 if success:
573 write('\tTook %s since pressing accept.' % str(timedelta(seconds=int(time.time() - time_table['screenshot_time']))), add_time=False, push=push_urgency + 1)
574 write('\tTook %s since trying to find a game.' % str(timedelta(seconds=int(time.time() - time_table['time_searching']))), add_time=False, push=push_urgency + 1)
575 write('Game should have started', push=push_urgency + 2, push_now=True)
576 truth_table['test_for_success'] = False
577 truth_table['test_for_warmup'] = True
578 playsound('sounds/done_testing.mp3')
579 time_table['warmup_test_timer'] = time.time() + 5
580 continue
581
582 if any([searching, not_searching]):
583 write('\tTook: %s ' % str(timedelta(seconds=int(time.time() - time_table['screenshot_time']))), add_time=False, push=push_urgency + 1)
584 write('Game doesnt seem to have started. Continuing to search for a Server!', push=push_urgency + 1, push_now=True)
585 playsound('sounds/back_to_testing.mp3')
586 truth_table['test_for_success'] = False
587 truth_table['test_for_server'] = True
588 continue
589
590 else:
591 write('40 Seconds after accept, did not find a loading map nor searching queue')
592 truth_table['test_for_success'] = False
593 # noinspection PyUnboundLocalVariable
594 print(success_avg)
595 # noinspection PyUnboundLocalVariable
596 print(searching_avg)
597 # noinspection PyUnboundLocalVariable
598 print(not_searching_avg)
599 playsound('sounds/fail.mp3')
600 # noinspection PyUnboundLocalVariable
601 img.save(cfg['debug_path'] + '\\Unknown Error.png')
602
603 if truth_table['test_for_warmup']:
604
605 for i in range(cfg['stop_warmup_ocr'][0], cfg['stop_warmup_ocr'][1]):
606 win32api.GetAsyncKeyState(i) & 1
607 while True:
608 keys = [(win32api.GetAsyncKeyState(i) & 1) for i in range(cfg['stop_warmup_ocr'][0], cfg['stop_warmup_ocr'][1])]
609
610 if any(keys):
611 write('Break from warmup-loop')
612 truth_table['test_for_warmup'] = False
613 truth_table['first_ocr'] = True
614 truth_table['first_push'] = True
615 break
616
617 if time.time() - time_table['warmup_test_timer'] >= cfg['warmup_test_interval']:
618 img = getScreenShot(hwnd, (1036, 425, 1525, 456)) # 'WAITING FOR PLAYERS X:XX'
619 img_text = Image_to_Text(img, img.size, (225, 225, 225), arg='--psm 6')
620 time_table['warmup_test_timer'] = time.time()
621 time_left = re.sub(inverted_warmup_time, "", img_text)
622 if time_left:
623 time_left = time_left.split()[-1].split(':')
624 # write(img_text, add_time=False)
625 try:
626 time_left = int(time_left[0]) * 60 + int(time_left[1])
627 if truth_table['first_ocr']:
628 join_warmup_time = time_left
629 time_table['screenshot_time'] = time.time()
630 truth_table['first_ocr'] = False
631
632 except (ValueError, IndexError):
633 continue
634
635 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
636 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')
637 if no_text_found > 0:
638 no_text_found = 0
639
640 if time_left <= push_times[push_counter]:
641 push_counter += 1
642 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, push_now=True, output=False)
643
644 if truth_table['first_push']:
645 if abs((join_warmup_time - time_left) - (time.time() - time_table['screenshot_time'])) >= 5:
646 truth_table['first_push'] = False
647 write('Match should start in ' + str(time_left) + ' seconds, All players have connected', push=push_urgency + 2, push_now=True)
648
649 else:
650 no_text_found += 1
651
652 if push_counter >= len(push_times):
653 push_counter = 0
654 no_text_found = 0
655 truth_table['test_for_warmup'] = False
656 truth_table['first_ocr'] = True
657 truth_table['first_push'] = True
658 write('Warmup should be over in less then %s seconds!' % push_times[-1], push=push_urgency + 2, push_now=True)
659 break
660
661 if no_text_found >= cfg['warmup_no_text_limit']:
662 push_counter = 0
663 no_text_found = 0
664 truth_table['test_for_warmup'] = False
665 truth_table['first_ocr'] = True
666 truth_table['first_push'] = True
667 write('Did not find any warmup text.', push=push_urgency + 2, push_now=True)
668 break
669if console_window['isatty']:
670 if last_printed_line.split(b'**')[-1] != b'\n':
671 print('')
672exit('ENDED BY USER')