├── .gitignore ├── LICENSE ├── README.md ├── requirements.txt └── src ├── autoaccept.py ├── build.py └── services ├── __init__.py ├── base.py └── mm.py /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | 5 | # C extensions 6 | *.so 7 | 8 | # Distribution / packaging 9 | .Python 10 | env/ 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | *.egg-info/ 23 | .installed.cfg 24 | *.egg 25 | 26 | # PyInstaller 27 | # Usually these files are written by a python script from a template 28 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 29 | *.manifest 30 | *.spec 31 | 32 | # Installer logs 33 | pip-log.txt 34 | pip-delete-this-directory.txt 35 | 36 | # Unit test / coverage reports 37 | htmlcov/ 38 | .tox/ 39 | .coverage 40 | .coverage.* 41 | .cache 42 | nosetests.xml 43 | coverage.xml 44 | *,cover 45 | 46 | # Translations 47 | *.mo 48 | *.pot 49 | 50 | # Django stuff: 51 | *.log 52 | 53 | # Sphinx documentation 54 | docs/_build/ 55 | 56 | # PyBuilder 57 | target/ 58 | 59 | # Built EXEs 60 | releases/ 61 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 James Dickens. (clug) 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # csgo-autoaccept 2 | Automatically detects and clicks the accept button in CS:GO matchmaking lobbies. 3 | 4 | In order for AutoAccept to work properly, you must either run CS:GO in windowed mode or disable Windows Aero features in fullscreen. 5 | 6 | ## Building 7 | AutoAccept is made into an executable using py2exe. The specific script I use can be found in the src directory. Once it is built it is packed using upx (level 9) and tagged as a new release in this repository. 8 | 9 | ## Known Bugs 10 | * The way the matchmaking detection service is designed requires a large amount of RGB colours to determine when the accept button shows up. There are over 1000 unique colours being scanned for, and as a result and lack of ability (and time) to fully test which colours **only** show up on the accept button, there is a chance the program will make a mistake and click somewhere the accept button is not. When this happens, please create an issue with the logfile so I can remove the colour that caused the misclick so that it does not happen again. 11 | 12 | ## TODO 13 | * Add other matchmaking services (ESEA, FaceIT, etc.) 14 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | Pillow==8.2.0 2 | PySide==1.2.2 3 | pywin32==219 4 | -------------------------------------------------------------------------------- /src/autoaccept.py: -------------------------------------------------------------------------------- 1 | """ 2 | csgo-autoaccept 3 | 4 | Automatically detects and clicks the accept button in CS:GO matchmaking lobbies. 5 | """ 6 | 7 | from __future__ import division 8 | 9 | import ctypes 10 | import logging 11 | import sys 12 | import webbrowser 13 | 14 | from PySide.QtCore import * 15 | from PySide.QtGui import * 16 | 17 | import services 18 | 19 | __author__ = "James \"clug\" " 20 | __version__ = "1.2.0" 21 | 22 | logging.basicConfig(filename="autoaccept.log", format="%(asctime)s - [%(levelname)s] %(name)s - %(message)s", level=logging.DEBUG) 23 | 24 | 25 | def click(x=False, y=False): 26 | if x and y: 27 | ctypes.windll.user32.SetCursorPos(int(x), int(y)) 28 | ctypes.windll.user32.mouse_event(0x02 | 0x04, 0, 0, 0, 0) 29 | 30 | 31 | class AutoAccept_GUI(QMainWindow): 32 | def __init__(self, *args, **kwargs): 33 | super(AutoAccept_GUI, self).__init__(*args, **kwargs) 34 | 35 | self.timer = QTimer(self) 36 | self.timer.setSingleShot(False) 37 | self.timer.timeout.connect(self.accept_scan) 38 | 39 | self.initUI() 40 | self.show() 41 | 42 | if services.base.aero_enabled(): 43 | self.warn_aero() 44 | 45 | def initUI(self): 46 | self.buttons = {} 47 | self.checkboxes = {} 48 | self.labels = {} 49 | self.layouts = {} 50 | self.widgets = {} 51 | 52 | self.setWindowTitle("AutoAccept") 53 | 54 | self.buttons["scan"] = QPushButton("&Scan") 55 | self.buttons["scan"].setCheckable(True) 56 | self.buttons["scan"].clicked[bool].connect(self.scan) 57 | 58 | self.buttons["help"] = QPushButton("&Help") 59 | self.buttons["help"].clicked.connect(self.help_info) 60 | self.layouts["buttons"] = QHBoxLayout() 61 | self.layouts["buttons"].addWidget(self.buttons["scan"]) 62 | self.layouts["buttons"].addWidget(self.buttons["help"]) 63 | 64 | self.checkboxes["loop"] = QCheckBox("Keep scanning after accepted") 65 | 66 | """self.checkboxes["mm"] = QCheckBox("MM") 67 | self.checkboxes["esea"] = QCheckBox("ESEA") 68 | self.checkboxes["faceit"] = QCheckBox("FaceIT")""" 69 | 70 | self.layouts["checkboxes"] = QHBoxLayout() 71 | for box in self.checkboxes: 72 | self.layouts["checkboxes"].addWidget(self.checkboxes[box]) 73 | 74 | self.labels["status"] = QLabel("
Scan is not running.
") 75 | 76 | self.layouts["main"] = QVBoxLayout() 77 | self.layouts["main"].addLayout(self.layouts["buttons"]) 78 | self.layouts["main"].addLayout(self.layouts["checkboxes"]) 79 | self.layouts["main"].addWidget(self.labels["status"]) 80 | self.widgets["main"] = QWidget() 81 | self.widgets["main"].setLayout(self.layouts["main"]) 82 | 83 | self.setCentralWidget(self.widgets["main"]) 84 | 85 | def accept_scan(self): 86 | found = services.mm.get_accept() 87 | if found: 88 | if not self.checkboxes["loop"].isChecked(): 89 | self.scan(False) 90 | click(*found) 91 | self.set_status("Found accept button.") 92 | 93 | def scan(self, on): 94 | if on: 95 | if not services.mm.exists(): 96 | self.critical_notrunning() 97 | on = False 98 | else: 99 | self.timer.start(1000) 100 | self.set_status("Scanning for accept button.") 101 | else: 102 | self.timer.stop() 103 | self.set_status("Scan is not running.") 104 | 105 | self.buttons["scan"].setChecked(on) 106 | 107 | def set_status(self, status): 108 | self.labels["status"].setText("
" + status + "
") 109 | 110 | def help_info(self): 111 | return webbrowser.open("http://github.com/clugg/csgo-autoaccept") 112 | 113 | def warn_aero(self): 114 | return QMessageBox.warning(self, "AutoAccept", "AutoAccept has detected that you have Windows Aero enabled. This will prevent Valve matchmaking detection from functioning properly if your game is not in windowed mode.", QMessageBox.Ok) 115 | 116 | def critical_notrunning(self): 117 | return QMessageBox.critical(self, "AutoAccept", "AutoAccept has detected that CS:GO is not running. Please launch CS:GO before starting a scan.", QMessageBox.Ok) 118 | 119 | 120 | if __name__ == "__main__": 121 | app = QApplication([]) 122 | gui = AutoAccept_GUI() 123 | sys.exit(app.exec_()) 124 | -------------------------------------------------------------------------------- /src/build.py: -------------------------------------------------------------------------------- 1 | import ctypes 2 | import fnmatch 3 | 4 | import os 5 | import sys 6 | 7 | from distutils.core import setup 8 | import py2exe 9 | 10 | if __name__ == "__main__": 11 | file_name = "autoaccept.py" 12 | module = __import__(os.path.basename(file_name.split(".")[0])) 13 | 14 | if not "py2exe" in sys.argv: 15 | sys.argv.append("py2exe") 16 | 17 | sys.path.append(r"C:\Program Files\Microsoft Visual Studio 9.0\VC\redist\x86\Microsoft.VC90.CRT") 18 | sys.path.append(r"C:\Python27\Lib\site-packages") 19 | 20 | setup(options = { 21 | "py2exe": { 22 | "compressed": 1, 23 | "optimize": 2, 24 | "bundle_files": 1, 25 | "includes": ["fnmatch", "ctypes"], 26 | "excludes": [ 27 | "pywin", "pywin.debugger", "pywin.debugger.dbgcon", 28 | "pywin.dialogs", "pywin.dialogs.list", "Tkconstants", "Tkinter", "tcl", 29 | "_ssl", "pyreadline", "doctest", "locale", "optparse", 30 | "calendar" 31 | ], 32 | "dll_excludes": ["oci.dll", "POWRPROF.dll", "msvcr71.dll"] 33 | } 34 | }, 35 | zipfile = None, 36 | windows = [file_name], 37 | name = "AutoAccept", 38 | version = module.__version__ if hasattr(module, "__version__") else "1.0.0", 39 | description = "AutoAccept", 40 | author = module.__author__ if hasattr(module, "__author__") else "James \"clug\" " 41 | ) 42 | -------------------------------------------------------------------------------- /src/services/__init__.py: -------------------------------------------------------------------------------- 1 | from . import base, mm 2 | -------------------------------------------------------------------------------- /src/services/base.py: -------------------------------------------------------------------------------- 1 | """ 2 | csgo-autoaccept 3 | 4 | Provides base functionality for all matchmaking services. 5 | """ 6 | 7 | import ctypes 8 | import re 9 | 10 | import win32api 11 | import win32gui 12 | from PIL import ImageGrab 13 | 14 | def aero_enabled(): 15 | """ 16 | Check if Windows Aero is enabled. 17 | 18 | Returns: 19 | bool: Whether or not Windows Aero is enabled. 20 | """ 21 | 22 | try: 23 | hasAero = ctypes.c_bool() 24 | retcode = ctypes.windll.dwmapi.DwmIsCompositionEnabled(ctypes.byref(hasAero)) 25 | return retcode == 0 and hasAero.value 26 | except AttributeError: 27 | return False 28 | 29 | def get_hwnd(window_title): 30 | """ 31 | Get the HWND for any window it can find. 32 | 33 | Returns: 34 | int: HWND of window if it is found. 35 | bool: False if no window exists. 36 | """ 37 | 38 | def _handle_hwnd(hwnds, hwnd, extra): 39 | if re.match(window_title, win32gui.GetWindowText(hwnd)): 40 | hwnds.append(hwnd) 41 | 42 | hwnds = [] 43 | win32gui.EnumWindows(lambda hwnd, extra: _handle_hwnd(hwnds, hwnd, extra), None) 44 | return hwnds[0] if hwnds else False 45 | 46 | def focused(window_title): 47 | """ 48 | Check if the window is focused (in the foreground). 49 | 50 | Returns: 51 | bool: Whether or not the window is focused. 52 | """ 53 | 54 | return win32gui.GetForegroundWindow() == get_hwnd(window_title) 55 | 56 | def exists(window_title): 57 | """ 58 | Check if it can find an open window. 59 | 60 | Returns: 61 | bool: Whether or not the window exists. 62 | """ 63 | 64 | return get_hwnd(window_title) is not False 65 | 66 | def screenshot(window_title): 67 | """ 68 | Take a screenshot of the window if it exists. 69 | 70 | Returns: 71 | Image: Image data for the screenshot taken. 72 | bool: False if no window exists. 73 | """ 74 | 75 | hwnd = get_hwnd(window_title) 76 | return ImageGrab.grab(win32gui.GetWindowRect(hwnd)) if hwnd else False 77 | -------------------------------------------------------------------------------- /src/services/mm.py: -------------------------------------------------------------------------------- 1 | """ 2 | csgo-autoaccept 3 | 4 | Provides specific functionality for Valve's official matchmaking service. 5 | """ 6 | 7 | import logging 8 | 9 | import base 10 | 11 | # use this to find csgo's hwnd 12 | WINDOW_TITLE = base.re.compile("^Counter-Strike: Global Offensive$") 13 | VALID_RGB = { 14 | (8, 59, 24), (0, 117, 75), (0, 107, 27), (74, 181, 139), (4, 89, 70), (5, 94, 73), 15 | (0, 96, 26), (9, 140, 99), (0, 127, 34), (222, 241, 233), (3, 71, 55), (33, 147, 110), 16 | (207, 234, 222), (232, 248, 240), (7, 55, 23), (6, 114, 81), (0, 123, 49), (3, 102, 76), 17 | (41, 138, 105), (31, 144, 108), (2, 83, 67), (221, 240, 232), (5, 131, 91), (81, 168, 137), 18 | (8, 106, 78), (70, 148, 122), (70, 159, 129), (17, 136, 97), (13, 145, 103), (2, 61, 19), 19 | (3, 75, 63), (4, 97, 73), (4, 128, 88), (20, 146, 105), (3, 84, 67), (51, 145, 112), 20 | (3, 83, 32), (14, 146, 103), (6, 97, 74), (0, 117, 28), (241, 249, 246), (1, 94, 72), 21 | (6, 53, 22), (214, 233, 225), (19, 145, 105), (6, 110, 80), (4, 67, 49), 22 | (3, 109, 79), (8, 113, 81), (6, 103, 77), (227, 246, 238), (4, 64, 44), (113, 182, 154), 23 | (22, 149, 108), (74, 165, 133), (2, 108, 79), (7, 112, 80), (40, 144, 108), (9, 132, 92), 24 | (157, 207, 188), (4, 117, 83), (8, 109, 80), (5, 102, 77), (0, 124, 49), (2, 84, 32), 25 | (0, 118, 77), (5, 83, 68), (156, 197, 182), (240, 249, 245), (51, 134, 103), (0, 120, 30), 26 | (1, 113, 81), (7, 91, 72), (150, 202, 182), (0, 99, 29), (4, 69, 53), (40, 154, 117), 27 | (84, 194, 150), (246, 251, 250), (188, 222, 208), (6, 134, 93), (7, 143, 101), (35, 155, 116), 28 | (20, 143, 104), (3, 98, 75), (1, 67, 19), (3, 85, 68), (5, 107, 78), (198, 224, 213), 29 | (2, 68, 39), (2, 84, 67), (0, 122, 32), (73, 163, 132), (154, 209, 190), (5, 69, 53), 30 | (50, 146, 112), (5, 106, 78), (3, 57, 19), (36, 149, 113), (0, 100, 69), (0, 96, 27), 31 | (0, 101, 70), (0, 73, 22), (6, 52, 21), (17, 137, 98), (15, 67, 35), (31, 161, 120), 32 | (209, 230, 222), (244, 251, 248), (16, 129, 92), (15, 136, 96), (3, 77, 64), (80, 170, 138), 33 | (76, 191, 144), (19, 136, 97), (32, 159, 118), (4, 57, 39), (1, 122, 85), (2, 81, 66), 34 | (0, 113, 39), (89, 177, 144), (30, 135, 99), (70, 158, 128), (218, 246, 233), (3, 72, 56), 35 | (206, 232, 221), (3, 130, 89), (0, 117, 76), (19, 108, 82), (9, 115, 83), (5, 115, 82), 36 | (6, 139, 97), (235, 249, 244), (49, 152, 116), (9, 65, 28), (6, 86, 69), (0, 124, 33), 37 | (6, 133, 92), (7, 114, 82), (113, 191, 159), (225, 242, 235), (0, 97, 73), (4, 77, 64), 38 | (202, 230, 219), (0, 107, 73), (7, 85, 69), (7, 88, 70), (3, 128, 87), (81, 162, 134), 39 | (3, 118, 83), (0, 129, 36), (1, 124, 85), (4, 96, 73), (230, 248, 240), (5, 98, 75), 40 | (0, 108, 27), (193, 221, 209), (4, 92, 71), (3, 84, 68), (227, 242, 236), (241, 250, 247), 41 | (6, 98, 75), (109, 169, 148), (8, 96, 74), (3, 86, 69), (28, 155, 115), (74, 158, 130), 42 | (36, 176, 130), (2, 100, 75), (148, 206, 185), (7, 135, 94), (63, 174, 132), (6, 115, 82), 43 | (54, 165, 128), (4, 109, 80), (4, 120, 84), (3, 102, 77), (3, 108, 78), 44 | (9, 119, 85), (249, 254, 252), (20, 141, 102), (6, 94, 72), (1, 86, 68), (1, 80, 28), 45 | (13, 145, 102), (3, 115, 81), (214, 238, 228), (4, 97, 74), (2, 90, 70), (1, 72, 46), 46 | (0, 107, 36), (9, 66, 29), (112, 185, 155), (47, 156, 120), (4, 76, 64), (238, 249, 244), 47 | (212, 233, 224), (12, 141, 99), (2, 82, 67), (222, 244, 234), (74, 188, 143), (16, 134, 96), 48 | (3, 92, 71), (190, 231, 214), (0, 123, 75), (73, 165, 133), (0, 130, 55), (45, 155, 118), 49 | (1, 97, 74), (81, 164, 135), (5, 112, 80), (92, 171, 142), (5, 103, 77), (0, 119, 30), 50 | (18, 134, 96), (6, 105, 78), (8, 78, 33), (4, 80, 66), (150, 203, 184), (41, 145, 110), 51 | (7, 112, 81), (196, 220, 211), (7, 133, 92), (196, 232, 216), (0, 91, 66), (102, 186, 152), 52 | (70, 155, 126), (7, 126, 87), (6, 145, 102), (3, 93, 72), (13, 124, 88), (3, 78, 64), 53 | (98, 179, 148), (3, 100, 75), (240, 249, 246), (22, 138, 100), (7, 80, 67), (9, 64, 28), 54 | (6, 137, 94), (24, 167, 122), (1, 101, 75), (153, 208, 189), (203, 231, 219), (4, 99, 75), 55 | (204, 229, 218), (3, 112, 80), (214, 239, 227), (10, 139, 98), (7, 143, 100), (5, 74, 61), 56 | (0, 92, 66), (194, 225, 212), (6, 84, 69), (18, 55, 37), (2, 96, 73), (70, 161, 129), 57 | (11, 134, 94), (4, 83, 67), (5, 96, 74), (236, 244, 241), (9, 138, 96), (5, 41, 18), 58 | (249, 253, 251), (81, 172, 139), (17, 133, 95), (0, 117, 44), (6, 89, 70), 59 | (1, 98, 75), (73, 166, 133), (8, 136, 95), (235, 247, 242), (6, 92, 72), (7, 98, 75), 60 | (4, 110, 80), (0, 118, 29), (0, 95, 26), (34, 145, 109), (2, 101, 76), (15, 142, 101), 61 | (5, 81, 67), (146, 194, 175), (8, 114, 81), (3, 127, 88), (0, 117, 77), (250, 254, 252), 62 | (46, 177, 132), (4, 129, 89), (1, 114, 81), (38, 161, 122), (226, 242, 236), (74, 159, 130), 63 | (24, 123, 91), (192, 230, 213), (2, 86, 68), (113, 191, 158), (241, 248, 246), (32, 132, 96), 64 | (5, 46, 34), (1, 70, 43), (202, 230, 218), (0, 107, 78), (231, 246, 240), (194, 230, 214), 65 | (6, 91, 72), (10, 126, 88), (2, 65, 35), (14, 135, 96), (73, 164, 132), (5, 145, 101), 66 | (0, 122, 30), (72, 188, 142), (1, 109, 79), (2, 113, 81), (6, 98, 74), (6, 83, 67), 67 | (8, 123, 86), (205, 231, 221), (8, 77, 34), (198, 234, 218), (2, 100, 74), (10, 68, 32), 68 | (172, 222, 202), (2, 106, 78), (29, 139, 103), (7, 108, 80), (94, 153, 134), (0, 96, 73), 69 | (5, 61, 42), (3, 108, 79), (15, 124, 89), (6, 85, 69), (6, 124, 86), (7, 113, 82), 70 | (0, 132, 59), (1, 80, 29), (6, 107, 78), (6, 90, 71), (13, 110, 81), (33, 165, 124), 71 | (4, 97, 75), (5, 129, 88), (9, 112, 80), (79, 167, 136), (0, 100, 75), (30, 162, 120), 72 | (153, 210, 190), (5, 85, 68), (71, 165, 132), (146, 199, 178), (224, 239, 233), (195, 226, 212), 73 | (89, 173, 143), (2, 82, 66), (8, 95, 73), (4, 75, 64), (4, 133, 92), (9, 63, 26), 74 | (0, 98, 33), (5, 127, 88), (0, 93, 66), (154, 208, 189), (0, 72, 22), (70, 163, 131), 75 | (0, 94, 71), (0, 103, 71), (16, 140, 100), (6, 93, 72), (2, 118, 82), (32, 167, 125), 76 | (239, 250, 244), (8, 132, 92), (3, 69, 53), (4, 55, 31), (0, 115, 42), (0, 128, 53), 77 | (52, 168, 128), (7, 138, 96), (2, 109, 79), (4, 86, 69), (0, 82, 60), (0, 77, 22), 78 | (2, 91, 70), (5, 112, 81), (86, 160, 135), (3, 123, 85), (236, 251, 245), 79 | (5, 76, 64), (8, 102, 77), (7, 88, 71), (0, 108, 37), (7, 119, 84), (7, 136, 95), 80 | (2, 92, 72), (1, 81, 30), (5, 96, 73), (0, 98, 74), (7, 118, 83), 81 | (1, 107, 78), (10, 75, 35), (217, 243, 231), (9, 124, 87), (6, 84, 68), (0, 99, 74), 82 | (171, 217, 200), (11, 129, 89), (0, 80, 20), (7, 100, 75), (1, 75, 48), (215, 235, 227), 83 | (37, 140, 104), (12, 129, 90), (5, 78, 65), (236, 249, 244), (5, 52, 37), (73, 157, 129), 84 | (12, 149, 105), (9, 122, 85), (27, 146, 108), (0, 86, 25), (13, 70, 35), (4, 91, 71), 85 | (2, 79, 64), (0, 133, 59), (244, 250, 248), (11, 68, 32), (0, 113, 81), (238, 248, 243), 86 | (5, 83, 34), (6, 109, 80), (5, 79, 65), (6, 88, 69), (0, 77, 25), (243, 250, 248), 87 | (48, 150, 116), (86, 157, 134), (5, 81, 66), (0, 99, 30), (213, 239, 228), (12, 112, 81), 88 | (7, 77, 33), (7, 106, 78), (8, 105, 78), (0, 117, 78), (240, 250, 246), (11, 129, 90), 89 | (3, 120, 84), (2, 88, 70), (13, 143, 101), (83, 154, 132), (2, 77, 64), (207, 234, 221), 90 | (214, 236, 227), (112, 186, 156), (7, 115, 83), (9, 128, 89), (3, 103, 76), (1, 74, 48), 91 | (0, 73, 21), (233, 245, 240), (245, 253, 250), (214, 242, 230), (247, 254, 250), (7, 93, 72), 92 | (3, 83, 33), (113, 192, 159), (8, 119, 85), (6, 135, 93), (25, 110, 84), (25, 145, 108), 93 | (0, 118, 45), (9, 63, 28), (6, 83, 68), (35, 133, 98), (0, 76, 25), (7, 140, 97), 94 | (0, 105, 72), (1, 78, 27), (8, 127, 88), (41, 122, 94), (75, 137, 116), (8, 117, 82), 95 | (166, 209, 195), (11, 130, 90), (35, 150, 113), (2, 106, 77), (93, 187, 150), (8, 122, 85), 96 | (205, 231, 220), (146, 198, 179), (5, 109, 79), (9, 114, 83), (0, 113, 40), (9, 115, 82), 97 | (0, 103, 76), (7, 101, 76), (16, 140, 99), (0, 115, 27), (247, 253, 250), (209, 232, 222), 98 | (155, 207, 188), (2, 93, 72), (0, 106, 34), (6, 107, 79), (4, 83, 34), (8, 139, 97), 99 | (34, 163, 123), (0, 105, 76), (9, 112, 81), (0, 110, 79), (0, 100, 74), (192, 229, 212), 100 | (10, 133, 93), (2, 94, 73), (7, 105, 78), (237, 248, 242), (5, 68, 51), (33, 158, 118), 101 | (0, 87, 64), (8, 24, 18), (10, 66, 31), (16, 133, 95), (0, 77, 26), (24, 157, 116), 102 | (32, 131, 97), (36, 139, 104), (4, 133, 93), (230, 246, 239), (157, 211, 192), (0, 99, 24), 103 | (11, 135, 95), (8, 117, 83), (239, 249, 245), (30, 147, 108), (5, 138, 96), (6, 127, 87), 104 | (5, 48, 20), (2, 66, 36), (0, 114, 41), (213, 238, 227), (0, 81, 58), (236, 245, 241), 105 | (5, 72, 57), (6, 82, 67), (78, 167, 136), (195, 228, 213), (0, 75, 24), (73, 160, 131), 106 | (1, 79, 28), (50, 167, 128), (2, 103, 76), (4, 66, 46), (12, 153, 109), (3, 106, 77), 107 | (10, 128, 88), (234, 245, 241), (7, 115, 82), (0, 112, 74), (212, 232, 224), (8, 102, 76), 108 | (0, 133, 60), (67, 149, 121), (34, 160, 120), (4, 131, 90), (4, 107, 79), (1, 90, 70), 109 | (33, 150, 113), (5, 75, 64), (222, 240, 232), (243, 249, 247), (86, 148, 130), (202, 225, 216), 110 | (0, 101, 31), (0, 109, 78), (146, 203, 181), (139, 191, 170), (229, 241, 236), (2, 84, 68), 111 | (7, 100, 76), (223, 240, 233), (0, 115, 35), (16, 135, 96), (0, 84, 23), (0, 109, 37), 112 | (10, 130, 91), (4, 93, 72), (5, 133, 92), (6, 52, 22), (6, 81, 67), (173, 217, 201), 113 | (52, 148, 115), (43, 165, 125), (0, 126, 51), (11, 68, 33), (6, 140, 97), (6, 48, 20), 114 | (5, 92, 72), (194, 227, 213), (8, 137, 95), (0, 122, 64), (19, 138, 100), (128, 207, 174), 115 | (206, 230, 220), (7, 99, 75), (213, 239, 227), (4, 91, 70), (134, 195, 170), (6, 75, 63), 116 | (7, 108, 79), (6, 127, 88), (16, 65, 36), (249, 254, 250), (2, 123, 85), (9, 124, 86), 117 | (0, 127, 75), (13, 143, 100), (251, 254, 252), (214, 236, 226), (16, 130, 93), (4, 130, 89), 118 | (243, 247, 246), (0, 130, 56), (51, 144, 111), (251, 253, 251), (3, 91, 70), (8, 114, 82), 119 | (4, 118, 83), (37, 148, 112), (7, 86, 69), (2, 82, 30), (0, 119, 45), (0, 107, 35), 120 | (2, 65, 33), (2, 99, 74), (214, 238, 227), (80, 166, 137), (194, 225, 211), (6, 135, 94), 121 | (0, 91, 34), (74, 164, 133), (10, 138, 97), (6, 92, 71), (1, 108, 78), (21, 127, 92), 122 | (32, 166, 123), (79, 168, 137), (6, 101, 76), (19, 155, 112), (3, 87, 69), (5, 100, 75), 123 | (2, 83, 32), (5, 118, 83), (6, 88, 70), (11, 130, 91), (36, 161, 122), (34, 149, 112), 124 | (244, 249, 248), (0, 97, 68), (195, 234, 217), (6, 108, 79), (30, 138, 102), (1, 119, 83), 125 | (2, 80, 66), (247, 253, 249), (8, 110, 80), (4, 59, 41), (9, 133, 92), (0, 99, 69), 126 | (86, 162, 137), (196, 229, 213), (222, 242, 233), (37, 144, 108), (1, 79, 27), (1, 72, 45), 127 | (0, 93, 24), (10, 149, 105), (0, 131, 58), (3, 107, 78), (2, 85, 68), (221, 242, 233), 128 | (234, 247, 241), (149, 205, 184), (2, 117, 82), (189, 223, 208), (4, 85, 69), (4, 117, 82), 129 | (7, 144, 101), (21, 133, 97), (9, 123, 86), (4, 103, 78), (148, 206, 184), (0, 99, 25), 130 | (86, 166, 138), (8, 137, 96), (239, 249, 244), (1, 93, 72), (5, 95, 74), (4, 73, 59), 131 | (5, 126, 86), (0, 83, 62), (0, 82, 21), (78, 165, 135), (1, 78, 26), (4, 79, 65), 132 | (208, 235, 223), (8, 93, 72), (45, 147, 112), (224, 242, 235), (34, 145, 108), 133 | (4, 88, 69), (12, 135, 95), (50, 151, 116), (17, 160, 115), (70, 157, 128), (6, 145, 101), 134 | (4, 114, 81), (35, 144, 107), (3, 80, 66), (60, 180, 135), (112, 187, 156), (70, 162, 130), 135 | (227, 243, 237), (23, 145, 106), (4, 65, 46), (6, 97, 75), (239, 250, 245), (4, 131, 91), 136 | (12, 133, 93), (2, 86, 69), (8, 131, 91), (17, 145, 103), (0, 122, 31), (170, 213, 199), 137 | (242, 251, 248), (7, 31, 18), (16, 120, 87), (113, 188, 158), (18, 61, 36), (4, 106, 77), 138 | (1, 110, 80), (2, 119, 83), (245, 251, 249), (4, 75, 62), (9, 103, 77), (5, 114, 81), 139 | (51, 153, 118), (23, 152, 110), (0, 128, 54), (109, 186, 155), (67, 159, 128), (2, 97, 74), 140 | (6, 50, 21), (10, 130, 90), (4, 74, 61), (5, 46, 19), (5, 84, 68), (0, 78, 25), 141 | (6, 40, 18), (0, 105, 33), (28, 140, 103), (239, 248, 243), (52, 148, 114), (2, 79, 66), 142 | (3, 96, 73), (246, 253, 250), (88, 163, 138), (175, 226, 205), (2, 112, 80), (5, 75, 63), 143 | (6, 113, 81), (0, 103, 32), (4, 66, 48), (234, 248, 241), (0, 90, 66), (68, 143, 116), 144 | (3, 59, 32), (0, 76, 50), (218, 235, 227), (2, 122, 85), (0, 76, 19), (4, 88, 70), 145 | (2, 123, 86), (36, 143, 107), (0, 112, 80), (10, 128, 89), (5, 137, 94), (5, 101, 75), 146 | (1, 73, 48), (229, 242, 238), (11, 72, 34), (0, 123, 32), (241, 248, 245), (151, 200, 181), 147 | (0, 81, 20), (19, 138, 99), (0, 91, 24), (3, 97, 73), (10, 120, 85), (0, 107, 77), 148 | (3, 72, 57), (0, 100, 31), (57, 137, 106), (226, 243, 236), (7, 138, 97), (1, 92, 72), 149 | (72, 176, 138), (97, 162, 139), (6, 95, 73), (5, 50, 21), (38, 143, 107), (6, 100, 75), 150 | (5, 81, 33), (1, 65, 18), (8, 120, 85), (1, 108, 79), (1, 102, 76), (0, 69, 19), 151 | (212, 236, 226), (0, 97, 27), (250, 253, 251), (16, 138, 98), (80, 163, 134), (3, 88, 69), 152 | (7, 91, 71), (4, 87, 69), (79, 147, 125), (5, 74, 63), (0, 84, 64), (2, 115, 81), 153 | (3, 95, 73), (8, 103, 77), (30, 138, 101), (3, 82, 66), (0, 126, 34), (11, 147, 103), 154 | (8, 129, 89), (36, 145, 110), (5, 45, 33), (11, 130, 89), (239, 247, 243), (0, 112, 39), 155 | (17, 148, 105), (33, 146, 109), (0, 72, 19), (7, 30, 19), (27, 127, 91), (3, 92, 72), 156 | (2, 85, 69), (4, 70, 53), (82, 167, 138), (2, 117, 83), (232, 242, 239), (10, 66, 29), 157 | (0, 113, 75), (0, 108, 34), (233, 243, 240), (6, 117, 83), (80, 165, 136), (51, 154, 119), 158 | (205, 229, 219), (143, 201, 178), (4, 103, 76), (1, 96, 73), (3, 99, 75), (215, 241, 229), 159 | (5, 126, 87), (10, 155, 110), (55, 148, 117), (0, 109, 64), (4, 84, 68), (4, 72, 59), 160 | (233, 242, 239), (1, 118, 82), (9, 135, 95), (0, 85, 64), (224, 242, 234), (6, 119, 84), 161 | (67, 176, 134), (6, 120, 85), (0, 127, 52), (17, 138, 98), (0, 101, 75), (8, 107, 79), 162 | (1, 105, 77), (6, 130, 89), (1, 91, 71), (3, 123, 86), (7, 141, 98), (50, 147, 114), 163 | (0, 133, 62), (132, 184, 162), (8, 147, 103), (96, 172, 144), (9, 134, 94), (241, 249, 247), 164 | (4, 122, 85), (14, 122, 88), (0, 94, 72), (5, 41, 19), (92, 181, 147), (0, 110, 39), 165 | (3, 76, 63), (18, 61, 37), (2, 119, 84), (245, 251, 248), (6, 96, 74), (57, 180, 135), 166 | (237, 245, 242), (5, 108, 79), (234, 247, 242), (232, 247, 240), (18, 143, 103), (5, 95, 73), 167 | (16, 132, 94), (10, 107, 79), (8, 138, 97), (194, 218, 208), (195, 230, 214), (0, 98, 29), 168 | (5, 122, 85), (5, 70, 55), (81, 165, 136), (167, 213, 196), (9, 108, 80), (216, 236, 227), 169 | (3, 89, 70), (3, 119, 83), (232, 243, 239), (191, 226, 210), (16, 133, 94), (15, 139, 99), 170 | (7, 122, 85), (70, 160, 129), (0, 103, 33), (164, 230, 204), (7, 98, 74), (4, 71, 57), 171 | (4, 68, 51), (2, 122, 84), (0, 122, 47), (4, 113, 81), (0, 94, 25), (6, 128, 88), 172 | (1, 84, 68), (3, 117, 82), (77, 152, 128), (0, 102, 32), (7, 135, 93), (0, 75, 23), 173 | (0, 127, 36), (50, 150, 115), (34, 148, 110), (1, 100, 75), (50, 155, 120), (223, 239, 232), 174 | (3, 75, 62), (4, 78, 65), (10, 131, 91), (5, 53, 39), (80, 164, 134), (212, 238, 226), 175 | (230, 244, 239), (7, 106, 79), (234, 244, 241), (0, 100, 30), (0, 115, 75), 176 | (36, 146, 110), (243, 250, 247), (103, 189, 155), (213, 236, 227), (2, 80, 29), (3, 101, 76), 177 | (24, 140, 101), (186, 215, 204), (233, 247, 240), (233, 244, 240), (94, 160, 137), (8, 59, 25), 178 | (11, 67, 31), (0, 97, 28), (115, 200, 163), (8, 127, 87), (5, 105, 77), (32, 148, 110), 179 | (137, 187, 166), (6, 87, 69), (146, 184, 169), (11, 123, 87), (204, 228, 218), (11, 142, 100), 180 | (14, 122, 87), (223, 243, 234), (2, 115, 82), (3, 95, 72), (73, 162, 131), (3, 134, 92), 181 | (3, 82, 67), (0, 74, 23), (46, 142, 109), (51, 149, 115), (0, 72, 21), (3, 124, 85), 182 | (4, 109, 79), (227, 239, 234), (0, 95, 72), (8, 61, 25), (213, 233, 225), (0, 128, 36), 183 | (36, 160, 120), (3, 107, 79), (46, 149, 114), (0, 101, 76), (156, 223, 197), (21, 142, 102), 184 | (73, 161, 131), (86, 193, 150), (12, 136, 96), (2, 99, 75), (14, 153, 108), (73, 157, 130), 185 | (16, 134, 95), (213, 238, 226), (235, 249, 242), (2, 120, 83), (12, 69, 34), (235, 248, 241), 186 | (28, 168, 124), (0, 94, 67), (0, 92, 23), (5, 115, 81), (213, 235, 226), (9, 114, 82), 187 | (82, 150, 129), (5, 80, 66), (5, 72, 59), (4, 84, 67), (6, 91, 71), (224, 239, 232), 188 | (25, 139, 102), (70, 161, 130), (5, 103, 76), (215, 241, 230), (7, 117, 83), 189 | (7, 124, 87), (72, 147, 124), (0, 110, 80), (3, 90, 70), (5, 77, 65), (206, 228, 218), 190 | (0, 118, 75), (6, 137, 95), (4, 71, 55), (1, 78, 54), (239, 248, 245), 191 | (6, 108, 80), (134, 212, 180), (1, 112, 80), (6, 112, 81), (4, 131, 89), (113, 183, 155), 192 | (198, 233, 217), (4, 138, 95), (4, 122, 84), (115, 187, 158), (2, 79, 65), (0, 89, 65), 193 | (7, 124, 86), (9, 110, 80), (26, 150, 111), (0, 117, 82), (3, 81, 67), 194 | (2, 91, 71), (0, 76, 24), (93, 161, 138), (5, 95, 72), (238, 247, 242), (4, 70, 55), 195 | (49, 152, 118), (3, 109, 80), (57, 148, 116), (8, 138, 96), (29, 146, 108), (10, 141, 100), 196 | (0, 98, 28), (0, 106, 77), (0, 96, 68), (10, 131, 92), (7, 109, 80), (3, 57, 18), 197 | (10, 129, 89), (7, 130, 91), (53, 176, 132), (113, 187, 157), (6, 140, 98), (20, 159, 116), 198 | (2, 65, 36), (8, 118, 83), (0, 72, 20), (15, 139, 98), (3, 94, 72), (164, 212, 194), 199 | (42, 147, 112), (15, 136, 97), (87, 167, 139), (18, 156, 113), (11, 110, 81), (0, 79, 56), 200 | (6, 123, 85), (35, 147, 109), (208, 227, 219), (3, 127, 87), (172, 209, 196), (8, 106, 79), 201 | (6, 79, 65), (5, 94, 72), (74, 162, 132), (3, 113, 81), (1, 99, 75), (1, 94, 71), 202 | (0, 102, 76), (14, 127, 90), (7, 120, 84), (2, 83, 66), (4, 118, 84), (3, 73, 59), 203 | (230, 244, 238), (0, 126, 36), (223, 241, 235), (0, 100, 29), (37, 145, 109), (70, 159, 128), 204 | (113, 189, 158), (17, 136, 96), (4, 72, 57), (5, 130, 90), (14, 66, 35), (9, 130, 90), 205 | (4, 75, 63), (14, 150, 107), (4, 106, 78), (6, 35, 19), (5, 77, 64), (1, 103, 76), 206 | (4, 100, 75), (232, 244, 239), (3, 87, 70), (0, 122, 75), (5, 70, 53), (37, 147, 110), 207 | (7, 57, 24), (5, 132, 91), (1, 76, 25), (11, 123, 86), (26, 157, 116), (0, 93, 71), 208 | (66, 133, 108), (26, 147, 108), (2, 69, 41), (0, 103, 72), (3, 89, 71), (96, 173, 144), 209 | (4, 46, 18), (3, 74, 61), (7, 87, 69), (3, 124, 86), (150, 205, 185), (0, 95, 73), 210 | (8, 61, 26), (213, 233, 224), (0, 128, 35), (2, 88, 69), (8, 133, 93), (1, 88, 69), 211 | (67, 182, 138), (5, 102, 76), (0, 131, 57), (191, 225, 210), (2, 84, 33), (0, 80, 56), 212 | (16, 170, 122), (9, 128, 88), (6, 130, 90), (2, 89, 70), (83, 160, 135), (11, 132, 93), 213 | (2, 76, 63), (2, 92, 71), (25, 156, 115), (5, 76, 65), (235, 248, 242), (0, 98, 73), 214 | (7, 89, 70), (10, 133, 92), (53, 159, 123), (4, 110, 79), (7, 79, 34), (0, 108, 73), 215 | (204, 229, 219), (3, 85, 69), (2, 87, 69), (5, 107, 79), (37, 151, 114), (2, 76, 64), 216 | (49, 156, 120), (7, 117, 82), (10, 153, 109), (8, 126, 87), (5, 106, 77), (7, 95, 74), 217 | (228, 239, 234), (154, 210, 190), (1, 95, 72), (2, 109, 80), (17, 131, 94), (214, 233, 226), 218 | (3, 78, 65), (251, 253, 253), (147, 201, 180), (2, 67, 38), (78, 171, 137), (3, 132, 91), 219 | (42, 176, 131), (217, 234, 228), (0, 108, 78), (3, 83, 67), (6, 112, 80), (5, 82, 67), 220 | (1, 87, 69), (3, 105, 77), (1, 92, 71), (16, 168, 121), (196, 233, 216), (113, 188, 157), 221 | (11, 138, 96), (1, 71, 43), (1, 89, 70), (0, 109, 74), (70, 156, 128), (1, 91, 70), 222 | (6, 55, 23), (46, 134, 101), (15, 126, 89), (96, 162, 140), (3, 81, 66), (232, 245, 240), 223 | (4, 102, 76), (206, 231, 221), (6, 139, 96), (238, 247, 243), (13, 118, 86), (98, 171, 145), 224 | (9, 65, 29), (7, 97, 74), (0, 114, 27), (5, 110, 80), (7, 92, 72), (110, 182, 154), 225 | (0, 120, 47), (4, 50, 36), (0, 91, 23), (3, 79, 65), (244, 250, 247), (6, 123, 86), 226 | (106, 160, 141), (0, 77, 52), (0, 115, 81), (12, 131, 92), (4, 81, 67), (5, 98, 74), 227 | (22, 150, 110), (97, 207, 162), (25, 145, 107), (99, 181, 149), (5, 99, 75) 228 | } 229 | 230 | log = logging.getLogger("services.mm") 231 | 232 | get_hwnd = lambda: base.get_hwnd(WINDOW_TITLE) 233 | focused = lambda: base.focused(WINDOW_TITLE) 234 | exists = lambda: base.exists(WINDOW_TITLE) 235 | screenshot = lambda: base.screenshot(WINDOW_TITLE) 236 | 237 | def get_accept(): 238 | """ 239 | Find the accept button if the CS:GO window exists. 240 | 241 | Returns: 242 | tuple: x, y coordinates of accept button. 243 | bool: False if no CS:GO window exists or no accept button is found. 244 | """ 245 | 246 | game = screenshot() 247 | if not game: 248 | log.debug("get_accept failed: csgo not running") 249 | return False 250 | elif not focused(): 251 | log.debug("get_accept failed: csgo not focused") 252 | return False 253 | 254 | startx, starty, _, _ = base.win32gui.GetWindowRect(get_hwnd()) 255 | w, h = game.size 256 | pixels = game.load() 257 | # assume button is in top left quarter of game window 258 | for x in range(0, w // 2, 4): # skip 4 horizontal pixels at a time due to vertical gradient 259 | for y in range(0, h // 2): 260 | if pixels[x, y] in VALID_RGB: 261 | log.debug("get_accept found valid colour {} at {}, {}".format(pixels[x, y], x, y)) 262 | return startx + x, starty + y 263 | log.debug("get_accept failed: accept not found") 264 | return False 265 | --------------------------------------------------------------------------------