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