· 6 years ago · Apr 24, 2020, 10:42 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_warmup_time = re.compile('\d+?:\d+')
384inverted_warmup_time = re.compile('[^\d:]')
385with open(csgo_path + 'console_log.log', 'w') as log:
386 log.write('')
387with open(cfg['debug_path'] + '\\console.log', 'w') as debug_log:
388 debug_log.write('')
389
390# INITIALIZATION FOR getScreenShot
391screen_width, screen_height = win32api.GetSystemMetrics(0), win32api.GetSystemMetrics(1)
392hwnd = 0
393toplist, csgo = [], []
394
395# BOOLEAN, TIME INITIALIZATION
396truth_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}
397time_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()}
398test_for_accept_counter = 0
399
400# csgostats.gg VAR
401retryer = []
402
403# WARMUP DETECTION SETUP
404pytesseract.pytesseract.tesseract_cmd = cfg['tesseract_path']
405no_text_found, push_counter = 0, 0
406push_times = [int(i) for i in cfg['warmup_push_interval'].split(',')]
407push_times.sort(reverse=True)
408join_warmup_time = push_times[0] + 1
409
410# PUSHBULLET VAR
411note = ''
412push_urgency = 0
413
414# MUTE CSGO PATH
415mute_csgo_path = '"' + os.getcwd() + '\\sounds\\nircmdc.exe" muteappvolume csgo.exe '
416mute_csgo(0)
417
418write('READY')
419write('Current account is: %s\n' % accounts[current_account]['name'], add_time=False)
420
421
422while True:
423 if win32api.GetAsyncKeyState(cfg['activate_script']) & 1: # F9 (ACTIVATE / DEACTIVATE SCRIPT)
424 truth_table['test_for_server'] = not truth_table['test_for_server']
425 write('TESTING: %s' % truth_table['test_for_server'], overwrite='1')
426 if truth_table['test_for_server']:
427 playsound('sounds/activated_2.mp3')
428 time_table['time_searching'] = time.time()
429 mute_csgo(1)
430 else:
431 playsound('sounds/deactivated.mp3')
432 mute_csgo(0)
433
434 if win32api.GetAsyncKeyState(cfg['activate_push_notification']) & 1: # F8 (ACTIVATE / DEACTIVATE PUSH NOTIFICATION)
435 if not device:
436 try:
437 device = pushbullet.PushBullet(cfg['pushbullet_api_key']).get_device(cfg['pushbullet_device_name'])
438 except (pushbullet.errors.PushbulletError, pushbullet.errors.InvalidKeyError):
439 write('Pushbullet is wrongly configured.\nWrong API Key or DeviceName in config.ini')
440 if device:
441 push_urgency += 1
442 if push_urgency > 3:
443 push_urgency = 0
444 push_info = ['not active', 'only if accepted', 'all game status related information', 'all information (game status/csgostats.gg information)']
445 write('Pushing: %s' % push_info[push_urgency], overwrite='2')
446
447 if win32api.GetAsyncKeyState(cfg['info_newest_match']) & 1: # F7 Key (UPLOAD NEWEST MATCH)
448 write('Uploading / Getting status on newest match')
449 queue_difference = []
450 new_sharecodes = getNewCSGOSharecodes(getOldSharecodes(-1)[0])
451 for new_code in new_sharecodes:
452 retryer.append(new_code) if new_code['sharecode'] not in [old_code['sharecode'] for old_code in retryer] else retryer
453 retryer = UpdateCSGOstats(retryer, get_all_games=True)
454
455 if win32api.GetAsyncKeyState(cfg['open_live_tab']) & 1: # F13 Key (OPEN WEB BROWSER ON LIVE GAME TAB)
456 win32gui.ShowWindow(hwnd, win32con.SW_MAXIMIZE)
457 webbrowser.open_new_tab('https://csgostats.gg/player/' + accounts[current_account]['steam_id'] + '#/live')
458 write('new tab opened', add_time=False)
459 time.sleep(0.5)
460 win32gui.ShowWindow(hwnd, win32con.SW_MAXIMIZE)
461
462 if win32api.GetAsyncKeyState(cfg['switch_accounts']) & 1: # F15 (SWITCH ACCOUNTS)
463 current_account += 1
464 if current_account > len(accounts) - 1:
465 current_account = 0
466 getCsgoPath(accounts[current_account]['steam_id_3'])
467 write('current account is: %s' % accounts[current_account]['name'], add_time=False, overwrite='3')
468
469 if win32api.GetAsyncKeyState(cfg['mute_csgo_toggle']) & 1: # POS1 (END SCRIPT)
470 write("MUTE TOGGLED", add_time=False)
471 mute_csgo(2)
472
473 if win32api.GetAsyncKeyState(cfg['end_script']) & 1: # POS1 (END SCRIPT)
474 write('Exiting Script')
475 break
476
477 if retryer:
478 if time.time() - time_table['time_since_retry'] > cfg['auto_retry_interval']:
479 retryer = UpdateCSGOstats(retryer)
480 winlist = []
481 win32gui.EnumWindows(enum_cb, toplist)
482 csgo = [(hwnd, title) for hwnd, title in winlist if 'counter-strike: global offensive' in title.lower()]
483 if not csgo:
484 continue
485 hwnd = csgo[0][0]
486
487 # TESTING HERE
488 if win32api.GetAsyncKeyState(0x6F) & 1: # UNBOUND, TEST CODE
489 # truth_table['debugging'] = not truth_table['debugging']
490 truth_table['test_for_warmup'] = not truth_table['test_for_warmup']
491 write('DEBUGGING: %s\n' % truth_table['debugging'])
492
493 if truth_table['testing']:
494 # time_table['screenshot_time'] = time.time()
495 pass
496 # print('Took: %s ' % str(timedelta(milliseconds=int(time.time(*1000 - time_table['screenshot_time']*1000))))
497 # TESTING ENDS HERE
498
499 if truth_table['test_for_server']:
500 if time.time() - time_table['searching_cc'] > 0.2:
501 time_table['searching_cc'] = time.time()
502 continue
503 with open(csgo_path + 'console_log.log', 'rb+') as log:
504 log_lines = log.readlines()
505 game_start = [line.decode('utf-8', 'ignore').encode("utf-8").rstrip(b'\n\r').decode() for line in log_lines]
506 log.seek(0)
507 log.truncate()
508 with open(cfg['debug_path'] + '\\console.log', 'ab') as debug_log:
509 [debug_log.write(i) for i in log_lines]
510 start = time.time_ns()
511 server_ready = any([bool(re.match(match_server_ready, i)) for i in game_start])
512 if server_ready:
513 test_for_accept_counter = 0
514 write('Server found, starting to look for accept button')
515 truth_table['test_for_accept_button'] = True
516 # truth_table['test_for_server'] = False
517 playsound('sounds/server_found.mp3')
518 win32gui.ShowWindow(hwnd, win32con.SW_MAXIMIZE)
519 else:
520 if time.time() - time_table['not_searching_cc'] > 20:
521 time_table['not_searching_cc'] = time.time()
522 with open(csgo_path + 'console_log.log', 'w') as log:
523 log.write('')
524
525 if truth_table['test_for_accept_button']:
526 if time.time() - time_table['screenshot_time'] < cfg['screenshot_interval']:
527 continue
528 time_table['screenshot_time'] = time.time()
529 img = getScreenShot(hwnd, (1265, 760, 1295, 785))
530 if not img:
531 continue
532 accept_avg = color_average(img, [(76, 176, 80), (89, 203, 94)])
533 mute_csgo(0)
534 if relate_list(accept_avg, [(2, 2, 2), (2, 2, 2)]):
535 write('Trying to Accept', push=push_urgency + 1)
536
537 truth_table['test_for_success'] = True
538 truth_table['test_for_accept_button'] = False
539 truth_table['test_for_server'] = False
540 accept_avg = []
541
542 for _ in range(5):
543 click(int(screen_width / 2), int(screen_height / 1.78))
544 pass
545
546 write('Trying to catch a loading map')
547 playsound('sounds/accept_found.mp3')
548 time_table['screenshot_time'] = time.time()
549 test_for_accept_counter += 1
550 if test_for_accept_counter > cfg['timeout_time']:
551 write('NO ACCEPT BUTTON FOUND AFTER %s seconds.' % str(cfg['timeout_time']*cfg['screenshot_interval']))
552 write('Continuing to look for ready server.')
553 mute_csgo(1)
554 truth_table['test_for_accept_button'] = False
555
556 if truth_table['test_for_success']:
557 if time.time() - time_table['screenshot_time'] < 40:
558 img = getScreenShot(hwnd, (2435, 65, 2555, 100))
559 not_searching_avg = color_average(img, [(6, 10, 10)])
560 searching_avg = color_average(img, [(6, 163, 97), (4, 63, 35)])
561
562 not_searching = relate_list(not_searching_avg, [(2, 5, 5)])
563 searching = relate_list(searching_avg, [(2.7, 55, 35), (1, 50, 35)])
564
565 img = getScreenShot(hwnd, (467, 1409, 1300, 1417))
566 success_avg = color_average(img, [(21, 123, 169)])
567 success = relate_list(success_avg, [(1, 8, 7)])
568
569 if success:
570 write('\tTook %s since pressing accept.' % str(timedelta(seconds=int(time.time() - time_table['screenshot_time']))), add_time=False, push=push_urgency + 1)
571 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)
572 write('Game should have started', push=push_urgency + 2, push_now=True)
573 truth_table['test_for_success'] = False
574 truth_table['test_for_warmup'] = True
575 playsound('sounds/done_testing.mp3')
576 time_table['warmup_test_timer'] = time.time() + 5
577 continue
578
579 if any([searching, not_searching]):
580 write('\tTook: %s ' % str(timedelta(seconds=int(time.time() - time_table['screenshot_time']))), add_time=False, push=push_urgency + 1)
581 write('Game doesnt seem to have started. Continuing to search for a Server!', push=push_urgency + 1, push_now=True)
582 playsound('sounds/back_to_testing.mp3')
583 truth_table['test_for_success'] = False
584 truth_table['test_for_server'] = True
585 continue
586
587 else:
588 write('40 Seconds after accept, did not find a loading map nor searching queue')
589 truth_table['test_for_success'] = False
590 # noinspection PyUnboundLocalVariable
591 print(success_avg)
592 # noinspection PyUnboundLocalVariable
593 print(searching_avg)
594 # noinspection PyUnboundLocalVariable
595 print(not_searching_avg)
596 playsound('sounds/fail.mp3')
597 # noinspection PyUnboundLocalVariable
598 img.save(cfg['debug_path'] + '\\Unknown Error.png')
599
600 if truth_table['test_for_warmup']:
601
602 for i in range(cfg['stop_warmup_ocr'][0], cfg['stop_warmup_ocr'][1]):
603 win32api.GetAsyncKeyState(i) & 1
604 while True:
605 keys = [(win32api.GetAsyncKeyState(i) & 1) for i in range(cfg['stop_warmup_ocr'][0], cfg['stop_warmup_ocr'][1])]
606
607 if any(keys):
608 write('Break from warmup-loop')
609 truth_table['test_for_warmup'] = False
610 truth_table['first_ocr'] = True
611 truth_table['first_push'] = True
612 break
613
614 if time.time() - time_table['warmup_test_timer'] >= cfg['warmup_test_interval']:
615 img = getScreenShot(hwnd, (1036, 425, 1525, 456)) # 'WAITING FOR PLAYERS X:XX'
616 img_text = Image_to_Text(img, img.size, (225, 225, 225), arg='--psm 6')
617 time_table['warmup_test_timer'] = time.time()
618 time_left = re.sub(inverted_warmup_time, "", img_text)
619 if time_left:
620 time_left = time_left.split()[-1].split(':')
621 # write(img_text, add_time=False)
622 try:
623 time_left = int(time_left[0]) * 60 + int(time_left[1])
624 if truth_table['first_ocr']:
625 join_warmup_time = time_left
626 time_table['screenshot_time'] = time.time()
627 truth_table['first_ocr'] = False
628
629 except (ValueError, IndexError):
630 continue
631
632 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
633 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')
634 if no_text_found > 0:
635 no_text_found = 0
636
637 if time_left <= push_times[push_counter]:
638 push_counter += 1
639 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)
640
641 if truth_table['first_push']:
642 if abs((join_warmup_time - time_left) - (time.time() - time_table['screenshot_time'])) >= 5:
643 truth_table['first_push'] = False
644 write('Match should start in ' + str(time_left) + ' seconds, All players have connected', push=push_urgency + 2, push_now=True)
645
646 else:
647 no_text_found += 1
648
649 if push_counter >= len(push_times):
650 push_counter = 0
651 no_text_found = 0
652 truth_table['test_for_warmup'] = False
653 truth_table['first_ocr'] = True
654 truth_table['first_push'] = True
655 write('Warmup should be over in less then %s seconds!' % push_times[-1], push=push_urgency + 2, push_now=True)
656 break
657
658 if no_text_found >= cfg['warmup_no_text_limit']:
659 push_counter = 0
660 no_text_found = 0
661 truth_table['test_for_warmup'] = False
662 truth_table['first_ocr'] = True
663 truth_table['first_push'] = True
664 write('Did not find any warmup text.', push=push_urgency + 2, push_now=True)
665 break
666if console_window['isatty']:
667 if last_printed_line.split(b'**')[-1] != b'\n':
668 print('')
669exit('ENDED BY USER')