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