· 6 years ago · Mar 23, 2020, 03:34 PM
1import configparser
2import operator
3import os
4import webbrowser
5from datetime import datetime, timedelta
6from time import time
7
8import pushbullet
9import pyperclip
10import requests
11import win32api
12import win32con
13import win32gui
14from PIL import ImageGrab
15from playsound import playsound
16
17
18def Avg(lst):
19 return sum(lst) / len(lst)
20
21
22def enum_cb(hwnd, results):
23 winlist.append((hwnd, win32gui.GetWindowText(hwnd)))
24
25
26def write(message, add_time=True, push=0, push_now=False):
27 if message:
28 if add_time:
29 m = datetime.now().strftime("%H:%M:%S") + ": " + str(message)
30 else:
31 m = message
32 print(m)
33
34 if push >= 3:
35 global note
36 if message:
37 note = note + m + "\n"
38 if push_now:
39 device.push_note("CSGO AUTO ACCEPT", note)
40 note = ""
41
42
43def click(x, y):
44 win32api.SetCursorPos((x, y))
45 win32api.mouse_event(win32con.MOUSEEVENTF_LEFTDOWN, x, y, 0, 0)
46 win32api.mouse_event(win32con.MOUSEEVENTF_LEFTUP, x, y, 0, 0)
47
48
49def relate_list(l_org, l1, l2=[], relate=operator.le):
50 if not l_org:
51 return False
52 truth_list, l3 = [], []
53 for i, val in enumerate(l1, start=0):
54 l3.append(relate(l_org[i], val))
55 truth_list.append(all(l3))
56 l3 = []
57 if l2:
58 for i, val in enumerate(l2, start=3):
59 l3.append(relate(l_org[i], val))
60 truth_list.append(all(l3))
61 return any(truth_list)
62
63
64def color_average(image, compare_list):
65 average = []
66 r, g, b = [], [], []
67 data = image.getdata()
68 for i in data:
69 r.append(i[0])
70 g.append(i[1])
71 b.append(i[2])
72
73 rgb = [Avg(r), Avg(g), Avg(b)] * int(len(compare_list) / 3)
74
75 for i, val in enumerate(compare_list, start=0):
76 average.append(val - rgb[i])
77 average = list(map(abs, average))
78
79 return average
80
81
82def getScreenShot(window_id, area=(0, 0, 0, 0)):
83 area = list(area)
84 scaled_area = [screen_width / 2560, screen_height / 1440]
85 scaled_area = 2 * scaled_area
86 for i, _ in enumerate(area[-2:], start=len(area) - 2):
87 area[i] += 1
88 for i, val in enumerate(area, start=0):
89 scaled_area[i] = scaled_area[i] * val
90 scaled_area = list(map(int, scaled_area))
91 win32gui.ShowWindow(window_id, win32con.SW_MAXIMIZE)
92 image = ImageGrab.grab(scaled_area)
93 return image
94
95
96def getOldSharecodes(num=-1):
97 try:
98 last_game = open("last_game.txt", "r")
99 games = last_game.readlines()
100 last_game.close()
101 except FileNotFoundError:
102 last_game = open("last_game.txt", "w")
103 last_game.write(config.get("csgostats.gg", "Match Token") + "\n")
104 games = [config.get("csgostats.gg", "Match Token")]
105 last_game.close()
106 last_game = open("last_game.txt", "w")
107 games = games[-200:]
108 for i, val in enumerate(games):
109 games[i] = "CSGO" + val.strip("\n").split("CSGO")[1]
110 last_game.write(games[i] + "\n")
111 last_game.close()
112 return games[num:]
113
114
115def getNewCSGOMatches(game_id):
116 sharecodes = []
117 next_code = game_id
118 last_game = open("last_game.txt", "a")
119 while next_code != "n/a":
120 steam_url = "https://api.steampowered.com/ICSGOPlayers_730/GetNextMatchSharingCode/v1?key=" + steam_api_key + "&steamid=" + steam_id + "&steamidkey=" + game_code + "&knowncode=" + game_id
121 try:
122 next_code = (requests.get(steam_url).json()["result"]["nextcode"])
123 except KeyError:
124 write("WRONG GAME_CODE, GAME_ID or STEAM_ID ")
125 return 0
126
127 if next_code:
128 if next_code != "n/a":
129 sharecodes.append(next_code)
130 game_id = next_code
131 last_game.write(next_code + "\n")
132 else:
133 write("Found %s Game[s]" % len(sharecodes))
134 return sharecodes
135
136
137def UpdateCSGOstats(sharecodes):
138 if any(sharecodes):
139 game_urls = []
140 for i, val in enumerate(sharecodes):
141 write('Sharecode: %s' % val, push=push_urgency)
142 response = requests.post("https://csgostats.gg/match/upload/ajax", data={'sharecode': val, 'index': '1'})
143 info = response.json()["data"]["msg"].split("<")[0].replace('-', '').rstrip(" ")
144 game_urls.append(response.json()["data"]["url"])
145 write("URL: %s" % game_urls[i], add_time=False, push=push_urgency)
146 write("Status: %s." % info, add_time=False, push=push_urgency)
147 # print(response.json())
148 write(None, add_time=False, push=push_urgency, push_now=True)
149 return game_urls
150
151
152def getHotKeys():
153 getKeys = []
154 getKeys.append(int(config.get("HotKeys", "Activate Script"), 16))
155 getKeys.append(int(config.get("HotKeys", "Activate Push Notification"), 16))
156 getKeys.append(int(config.get("HotKeys", "Upload newest Match"), 16))
157 getKeys.append(int(config.get("HotKeys", "Get Info on newest Match"), 16))
158 getKeys.append(int(config.get("HotKeys", "Get Info on multiple Matches"), 16))
159 getKeys.append(int(config.get("HotKeys", "Live Tab Key"), 16))
160 getKeys.append(int(config.get("HotKeys", "End Script"), 16))
161 getKeys.append(int(config.get("Screenshot", "Interval"), 16))
162 return getKeys
163
164
165config = configparser.ConfigParser()
166config.read("config.ini")
167
168steam_api_key = config.get("csgostats.gg", "API Key")
169steam_id = config.get("csgostats.gg", "Steam ID")
170game_code = config.get("csgostats.gg", "Game Code")
171
172keys = getHotKeys()
173
174device = 0
175
176screen_width, screen_height = win32api.GetSystemMetrics(0), win32api.GetSystemMetrics(1)
177toplist, winlist = [], []
178hwnd = 0
179
180test_for_live_game, test_for_success, push_urgency, testing = False, False, False, False
181accept_avg = []
182
183note = ""
184
185start_time = time()
186write("Ready")
187
188while True:
189 if win32api.GetAsyncKeyState(keys[0]) & 1: # F9 (ACTIVATE / DEACTIVATE SCRIPT)
190 test_for_live_game = not test_for_live_game
191 write("TESTING: %s" % test_for_live_game)
192 if test_for_live_game:
193 playsound('sounds/activated.mp3')
194 time_searching = time()
195 else:
196 playsound('sounds/deactivated.mp3')
197
198 if win32api.GetAsyncKeyState(keys[1]) & 1: # F8 (ACTIVATE / DEACTIVATE PUSH NOTIFICATION)
199 if not device:
200 PushBulletDeviceName = config.get('Pushbullet', 'DeviceName')
201 PushBulletAPIKey = config.get('Pushbullet', 'API Key')
202 try:
203 device = pushbullet.PushBullet(PushBulletAPIKey).get_device(PushBulletDeviceName)
204 except pushbullet.errors.PushbulletError or pushbullet.errors.InvalidKeyError:
205 write("Pushbullet is wrongly configured.\nWrong API Key or DeviceName in config.ini")
206 if device:
207 push_urgency += 1
208 if push_urgency > 3:
209 push_urgency = 0
210 push_info = ["not active", "only if accepted", "all game status related information", "all information (game Status/csgostats.gg information)"]
211 write("Pushing: %s" % push_info[push_urgency])
212
213 if win32api.GetAsyncKeyState(keys[2]) & 1: # F7 Key (UPLOAD NEWEST MATCH)
214 newest_match = getNewCSGOMatches(getOldSharecodes()[0])
215 if newest_match:
216 pyperclip.copy(UpdateCSGOstats(newest_match)[-1])
217 # UpdateCSGOstats(newest_match)
218
219 if win32api.GetAsyncKeyState(keys[3]) & 1: # F6 Key (GET INFO ON NEWEST MATCH)
220 pyperclip.copy(UpdateCSGOstats(getOldSharecodes())[-1])
221
222 if win32api.GetAsyncKeyState(keys[4]) & 1: # F5 Key (GET INFO ON LAST X MATCHES)
223 last_x_matches = config.getint("csgostats.gg", "Get Info from")
224 write("Getting Info from last %s matches" % last_x_matches)
225 UpdateCSGOstats(getOldSharecodes(num=last_x_matches * -1))
226
227 if win32api.GetAsyncKeyState(keys[5]) & 1: # F13 Key (OPEN WEB BROWSER ON LIVE GAME TAB)
228 webbrowser.open_new_tab("https://csgostats.gg/player/" + steam_id + "#/live")
229
230 if win32api.GetAsyncKeyState(keys[6]) & 1: # POS1/HOME Key
231 write("Exiting Script")
232 break
233
234 winlist = []
235 win32gui.EnumWindows(enum_cb, toplist)
236 csgo = [(hwnd, title) for hwnd, title in winlist if 'counter-strike: global offensive' in title.lower()]
237 if not csgo:
238 continue
239 hwnd = csgo[0][0]
240
241 # TESTING HERE
242 if win32api.GetAsyncKeyState(0x73) & 1: # F5, TEST CODE
243 write("Executing TestCode")
244 testing = not testing
245
246 if testing:
247 # start_time = time()
248 img = getScreenShot(hwnd, (2435, 65, 2555, 100))
249 not_searching_avg = color_average(img, [6, 10, 10])
250 searching_avg = color_average(img, [6, 163, 97, 4, 63, 35])
251 not_searching = relate_list(not_searching_avg, [2, 5, 5])
252 searching = relate_list(searching_avg, [2.7, 55, 35], l2=[1, 50, 35])
253 img = getScreenShot(hwnd, (467, 1409, 1300, 1417))
254 success_avg = color_average(img, [21, 123, 169])
255 success = relate_list(success_avg, [1, 8, 7])
256 # print("Took: %s " % str(timedelta(milliseconds=int(time()*1000 - start_time*1000))))
257 # TESTING ENDS HERE
258
259 if test_for_live_game:
260 if time() - start_time < keys[-1]:
261 continue
262 start_time = time()
263 img = getScreenShot(hwnd, (1265, 760, 1295, 785))
264 if not img:
265 continue
266 accept_avg = color_average(img, [76, 176, 80, 90, 203, 95])
267
268 if relate_list(accept_avg, [1, 2, 1], l2=[1, 1, 2]):
269 write("Trying to Accept", push=push_urgency+1)
270
271 test_for_success = True
272 test_for_live_game = False
273 accept_avg = []
274
275 for _ in range(5):
276 click(int(screen_width / 2), int(screen_height / 1.78))
277 # sleep(0.5)
278 # pass
279
280 write("Trying to catch a loading map")
281 playsound('sounds/accept_found.mp3')
282 start_time = time()
283
284 if test_for_success:
285 if time() - start_time < 40:
286 img = getScreenShot(hwnd, (2435, 65, 2555, 100))
287 not_searching_avg = color_average(img, [6, 10, 10])
288 searching_avg = color_average(img, [6, 163, 97, 4, 63, 35])
289
290 not_searching = relate_list(not_searching_avg, [2, 5, 5])
291 searching = relate_list(searching_avg, [2.7, 55, 35], l2=[1, 50, 35])
292
293 img = getScreenShot(hwnd, (467, 1409, 1300, 1417))
294 success_avg = color_average(img, [21, 123, 169])
295 success = relate_list(success_avg, [1, 8, 7])
296
297 if success:
298 write("Took %s since pressing accept." % str(timedelta(seconds=int(time() - start_time))), add_time=False, push=push_urgency+1)
299 write("Took %s since trying to find a game." % str(timedelta(seconds=int(time() - time_searching))), add_time=False, push=push_urgency+1)
300 write("Game should have started", push=push_urgency + 2, push_now=True)
301 test_for_success = False
302 playsound('sounds/done_testing.mp3')
303
304 if any([searching, not_searching]):
305 write("Took: %s " % str(timedelta(seconds=int(time() - start_time))), add_time=False, push=push_urgency+1)
306 write("Game doesnt seem to have started. Continuing to search for accept Button!", push=push_urgency+1, push_now=True)
307 playsound('sounds/back_to_testing.mp3')
308 test_for_success = False
309 test_for_live_game = True
310
311 else:
312 write("40 Seconds after accept, did not find loading map nor searching queue")
313 test_for_success = False
314 print(success_avg)
315 print(searching_avg)
316 print(not_searching_avg)
317 playsound('sounds/fail.mp3')
318 img.save(os.path.expanduser("~") + '\\Unknown Error.png')