├── .idea ├── .gitignore ├── vcs.xml ├── misc.xml ├── inspectionProfiles │ └── profiles_settings.xml ├── discord.xml ├── modules.xml └── lol-leveling-bot.iml ├── README.md ├── lol-leveling-bot ├── search_images │ ├── ok.png │ ├── ashe.png │ ├── shop.png │ ├── accept.png │ ├── annie.png │ ├── clash.png │ ├── confirm.png │ ├── garen.png │ ├── lockin.png │ ├── party.png │ ├── recall.png │ ├── continue.png │ ├── level_30.png │ ├── masteryi.png │ ├── ok_daily.png │ ├── choose_champ.png │ ├── coop_vs_ai.png │ ├── daily_play.png │ ├── edit_runes.png │ ├── find_match.png │ ├── key_fragment.png │ ├── lock_camera.png │ ├── play_again.png │ ├── play_button.png │ ├── select_daily.png │ ├── send_email.png │ ├── send_email_X.png │ ├── skip_honor.png │ ├── daily_play_ekko.png │ ├── daily_play_illaoi.png │ ├── daily_play_thresh.png │ ├── daily_play_ziggs.png │ ├── intermediate_bots.png │ ├── riot_client_play.png │ ├── daily_play_caitlyn.png │ ├── daily_play_missions.png │ └── ok_champ_select_bug.png ├── main.py ├── regions.py ├── globals.py ├── pictures.py ├── listener.py ├── utilities.py ├── bot_settings │ ├── game.cfg │ └── input.ini └── robot.py ├── .gitignore └── requirements.txt /.idea/.gitignore: -------------------------------------------------------------------------------- 1 | # Default ignored files 2 | /shelf/ 3 | /workspace.xml 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # lol-leveling-bot 2 | A League of Legends leveling bot which automatically queues up, plays the game, and collects rewards. -------------------------------------------------------------------------------- /lol-leveling-bot/search_images/ok.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ee3213/lol-leveling-bot/HEAD/lol-leveling-bot/search_images/ok.png -------------------------------------------------------------------------------- /lol-leveling-bot/search_images/ashe.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ee3213/lol-leveling-bot/HEAD/lol-leveling-bot/search_images/ashe.png -------------------------------------------------------------------------------- /lol-leveling-bot/search_images/shop.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ee3213/lol-leveling-bot/HEAD/lol-leveling-bot/search_images/shop.png -------------------------------------------------------------------------------- /lol-leveling-bot/search_images/accept.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ee3213/lol-leveling-bot/HEAD/lol-leveling-bot/search_images/accept.png -------------------------------------------------------------------------------- /lol-leveling-bot/search_images/annie.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ee3213/lol-leveling-bot/HEAD/lol-leveling-bot/search_images/annie.png -------------------------------------------------------------------------------- /lol-leveling-bot/search_images/clash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ee3213/lol-leveling-bot/HEAD/lol-leveling-bot/search_images/clash.png -------------------------------------------------------------------------------- /lol-leveling-bot/search_images/confirm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ee3213/lol-leveling-bot/HEAD/lol-leveling-bot/search_images/confirm.png -------------------------------------------------------------------------------- /lol-leveling-bot/search_images/garen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ee3213/lol-leveling-bot/HEAD/lol-leveling-bot/search_images/garen.png -------------------------------------------------------------------------------- /lol-leveling-bot/search_images/lockin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ee3213/lol-leveling-bot/HEAD/lol-leveling-bot/search_images/lockin.png -------------------------------------------------------------------------------- /lol-leveling-bot/search_images/party.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ee3213/lol-leveling-bot/HEAD/lol-leveling-bot/search_images/party.png -------------------------------------------------------------------------------- /lol-leveling-bot/search_images/recall.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ee3213/lol-leveling-bot/HEAD/lol-leveling-bot/search_images/recall.png -------------------------------------------------------------------------------- /lol-leveling-bot/search_images/continue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ee3213/lol-leveling-bot/HEAD/lol-leveling-bot/search_images/continue.png -------------------------------------------------------------------------------- /lol-leveling-bot/search_images/level_30.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ee3213/lol-leveling-bot/HEAD/lol-leveling-bot/search_images/level_30.png -------------------------------------------------------------------------------- /lol-leveling-bot/search_images/masteryi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ee3213/lol-leveling-bot/HEAD/lol-leveling-bot/search_images/masteryi.png -------------------------------------------------------------------------------- /lol-leveling-bot/search_images/ok_daily.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ee3213/lol-leveling-bot/HEAD/lol-leveling-bot/search_images/ok_daily.png -------------------------------------------------------------------------------- /lol-leveling-bot/search_images/choose_champ.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ee3213/lol-leveling-bot/HEAD/lol-leveling-bot/search_images/choose_champ.png -------------------------------------------------------------------------------- /lol-leveling-bot/search_images/coop_vs_ai.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ee3213/lol-leveling-bot/HEAD/lol-leveling-bot/search_images/coop_vs_ai.png -------------------------------------------------------------------------------- /lol-leveling-bot/search_images/daily_play.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ee3213/lol-leveling-bot/HEAD/lol-leveling-bot/search_images/daily_play.png -------------------------------------------------------------------------------- /lol-leveling-bot/search_images/edit_runes.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ee3213/lol-leveling-bot/HEAD/lol-leveling-bot/search_images/edit_runes.png -------------------------------------------------------------------------------- /lol-leveling-bot/search_images/find_match.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ee3213/lol-leveling-bot/HEAD/lol-leveling-bot/search_images/find_match.png -------------------------------------------------------------------------------- /lol-leveling-bot/search_images/key_fragment.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ee3213/lol-leveling-bot/HEAD/lol-leveling-bot/search_images/key_fragment.png -------------------------------------------------------------------------------- /lol-leveling-bot/search_images/lock_camera.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ee3213/lol-leveling-bot/HEAD/lol-leveling-bot/search_images/lock_camera.png -------------------------------------------------------------------------------- /lol-leveling-bot/search_images/play_again.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ee3213/lol-leveling-bot/HEAD/lol-leveling-bot/search_images/play_again.png -------------------------------------------------------------------------------- /lol-leveling-bot/search_images/play_button.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ee3213/lol-leveling-bot/HEAD/lol-leveling-bot/search_images/play_button.png -------------------------------------------------------------------------------- /lol-leveling-bot/search_images/select_daily.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ee3213/lol-leveling-bot/HEAD/lol-leveling-bot/search_images/select_daily.png -------------------------------------------------------------------------------- /lol-leveling-bot/search_images/send_email.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ee3213/lol-leveling-bot/HEAD/lol-leveling-bot/search_images/send_email.png -------------------------------------------------------------------------------- /lol-leveling-bot/search_images/send_email_X.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ee3213/lol-leveling-bot/HEAD/lol-leveling-bot/search_images/send_email_X.png -------------------------------------------------------------------------------- /lol-leveling-bot/search_images/skip_honor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ee3213/lol-leveling-bot/HEAD/lol-leveling-bot/search_images/skip_honor.png -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /venv/ 2 | /user_settings/ 3 | /lol-leveling-bot/user_settings/input.ini 4 | /lol-leveling-bot/user_settings/game.cfg 5 | /lol-leveling-bot/test.py 6 | -------------------------------------------------------------------------------- /lol-leveling-bot/search_images/daily_play_ekko.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ee3213/lol-leveling-bot/HEAD/lol-leveling-bot/search_images/daily_play_ekko.png -------------------------------------------------------------------------------- /lol-leveling-bot/search_images/daily_play_illaoi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ee3213/lol-leveling-bot/HEAD/lol-leveling-bot/search_images/daily_play_illaoi.png -------------------------------------------------------------------------------- /lol-leveling-bot/search_images/daily_play_thresh.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ee3213/lol-leveling-bot/HEAD/lol-leveling-bot/search_images/daily_play_thresh.png -------------------------------------------------------------------------------- /lol-leveling-bot/search_images/daily_play_ziggs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ee3213/lol-leveling-bot/HEAD/lol-leveling-bot/search_images/daily_play_ziggs.png -------------------------------------------------------------------------------- /lol-leveling-bot/search_images/intermediate_bots.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ee3213/lol-leveling-bot/HEAD/lol-leveling-bot/search_images/intermediate_bots.png -------------------------------------------------------------------------------- /lol-leveling-bot/search_images/riot_client_play.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ee3213/lol-leveling-bot/HEAD/lol-leveling-bot/search_images/riot_client_play.png -------------------------------------------------------------------------------- /lol-leveling-bot/search_images/daily_play_caitlyn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ee3213/lol-leveling-bot/HEAD/lol-leveling-bot/search_images/daily_play_caitlyn.png -------------------------------------------------------------------------------- /lol-leveling-bot/search_images/daily_play_missions.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ee3213/lol-leveling-bot/HEAD/lol-leveling-bot/search_images/daily_play_missions.png -------------------------------------------------------------------------------- /lol-leveling-bot/search_images/ok_champ_select_bug.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ee3213/lol-leveling-bot/HEAD/lol-leveling-bot/search_images/ok_champ_select_bug.png -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /.idea/inspectionProfiles/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | -------------------------------------------------------------------------------- /.idea/discord.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | -------------------------------------------------------------------------------- /lol-leveling-bot/main.py: -------------------------------------------------------------------------------- 1 | import robot 2 | import utilities 3 | import listener 4 | 5 | 6 | if __name__ == '__main__': 7 | # Perform setup 8 | utilities.setup() 9 | 10 | # Create listener thread 11 | listener.create_thread() 12 | 13 | # Run bot 14 | robot.run() 15 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | comtypes==1.1.11 2 | MouseInfo==0.1.3 3 | numpy==1.20.0 4 | opencv-python==4.5.1.48 5 | Pillow==8.1.0 6 | psutil==5.8.0 7 | PyAutoGUI==0.9.52 8 | PyGetWindow==0.0.9 9 | PyMsgBox==1.0.9 10 | pynput==1.7.2 11 | pyperclip==1.8.1 12 | PyRect==0.1.4 13 | PyScreeze==0.1.26 14 | PyTweening==1.0.3 15 | pywin32==300 16 | pywinauto==0.6.8 17 | pyWinhook==1.6.2 18 | six==1.15.0 19 | -------------------------------------------------------------------------------- /lol-leveling-bot/regions.py: -------------------------------------------------------------------------------- 1 | # Button Coordinates 2 | game_lockscreen_coords = (1068, 735) 3 | 4 | # Button Scanning regions 5 | play_button = (63, 21, 187, 59) 6 | party_button = (63, 21, 187, 59) 7 | coop_vs_ai = (88, 79, 205, 117) 8 | intermediate_bots = (403, 540, 556, 565) 9 | confirm = (420, 663, 633, 710) 10 | find_match = (423, 662, 634, 708) 11 | accept = (538, 524, 744, 584) 12 | champ_select = (343, 123, 936, 586) 13 | choose_champ = (435, 13, 839, 44) 14 | lockin = (550, 580, 733, 629) 15 | -------------------------------------------------------------------------------- /lol-leveling-bot/globals.py: -------------------------------------------------------------------------------- 1 | # Setting variables 2 | pause_key = "F6" 3 | move_windows_key = "F7" 4 | 5 | # Numerical variables 6 | number_of_games_finished = 0 7 | go_flag = 1 8 | stop_flag = 0 9 | time_since_last_click = 0 10 | 11 | # String variables 12 | last_status = None 13 | 14 | # File variables 15 | lol_client_path = None 16 | picture_path = None 17 | files_to_replace = ['game.cfg', 'input.ini'] 18 | 19 | # Thread variables 20 | listener_thread = None 21 | listener_thread_id = None 22 | bot_thread = None 23 | -------------------------------------------------------------------------------- /.idea/lol-leveling-bot.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /lol-leveling-bot/pictures.py: -------------------------------------------------------------------------------- 1 | 2 | 3 | accept = "accept.png" 4 | annie = "annie.png" 5 | ashe = "ashe.png" 6 | clash = "clash.png" 7 | confirm = "confirm.png" 8 | coop_vs_ai = "coop_vs_ai.png" 9 | daily_play = "daily_play.png" 10 | daily_play_missions = "daily_play_missions.png" 11 | daily_play_caitlyn = "daily_play_caitlyn.png" 12 | daily_play_ekko = "daily_play_ekko.png" 13 | daily_play_illaoi = "daily_play_illaoi.png" 14 | daily_play_thresh = "daily_play_thresh.png" 15 | daily_play_ziggs = "daily_play_ziggs.png" 16 | find_match = "find_match.png" 17 | garen = "garen.png" 18 | intermediate_bots = "intermediate_bots.png" 19 | lockin = "lockin.png" 20 | masteryi = "masteryi.png" 21 | ok = "ok.png" 22 | ok_daily = "ok_daily.png" 23 | party = "party.png" 24 | play_again = "play_again.png" 25 | play_button = "play_button.png" 26 | recall = "recall.png" 27 | riot_client_play = "riot_client_play.png" 28 | select_daily = "select_daily.png" 29 | shop = "shop.png" 30 | skip_honor = "skip_honor.png" 31 | trinket = "trinket.png" 32 | edit_runes = "edit_runes.png" 33 | choose_champ = "choose_champ.png" 34 | ok_champ_select_bug = "ok_champ_select_bug.png" 35 | level_30 = "level_30.png" 36 | key_fragment = "key_fragment.png" 37 | lock_camera = "lock_camera.png" 38 | continue_btn = "continue.png" 39 | -------------------------------------------------------------------------------- /lol-leveling-bot/listener.py: -------------------------------------------------------------------------------- 1 | # @author: Mitchell Levesque # 2 | # @desc : A file that listens for global key presses to handle pausing hotkeys # 3 | 4 | import threading 5 | 6 | import pyWinhook 7 | import pythoncom 8 | import win32api 9 | import win32con 10 | import time 11 | 12 | import globals 13 | import robot 14 | import utilities 15 | 16 | 17 | def on_keyboard_event(event): 18 | if event.Key == globals.pause_key: 19 | robot.set_to_pause() 20 | elif event.Key == globals.move_windows_key: 21 | utilities.move_windows() 22 | # return True to pass the event to other handlers 23 | return True 24 | 25 | 26 | def hook_keyboard(): 27 | # save the id of the thread 28 | globals.listener_thread_id = threading.get_ident() 29 | 30 | # create a hook manager 31 | hm = pyWinhook.HookManager() 32 | # watch for all mouse events 33 | hm.KeyDown = on_keyboard_event 34 | # set the hook 35 | hm.HookKeyboard() 36 | # wait forever 37 | pythoncom.PumpMessages() 38 | 39 | 40 | def create_thread(): 41 | globals.listener_thread = threading.Thread(target=hook_keyboard) 42 | globals.listener_thread.start() 43 | 44 | 45 | def stop(): 46 | if globals.listener_thread_id is not None: 47 | win32api.PostThreadMessage(globals.listener_thread_id, win32con.WM_QUIT, 0, 0) 48 | -------------------------------------------------------------------------------- /lol-leveling-bot/utilities.py: -------------------------------------------------------------------------------- 1 | import shutil 2 | import os 3 | 4 | import pyautogui 5 | import pywinauto.win32functions 6 | import win32gui 7 | from pywinauto.findwindows import find_window 8 | 9 | import globals 10 | 11 | bot_settings_path = os.path.join(os.getcwd(), "bot_settings") 12 | lol_settings_path = "C:\\Riot Games\\League of Legends\\Config" 13 | 14 | 15 | def setup(): 16 | globals.picture_path = os.path.join(os.getcwd(), "search_images") 17 | find_league_location() 18 | set_bot_files() 19 | 20 | 21 | def find_league_location(): 22 | global lol_settings_path 23 | print("Attempting to locate League of Legends...") 24 | for r, d, f in os.walk("C:\\"): 25 | for files in f: 26 | if files == "LeagueClient.exe": 27 | print("Successfully found %s" % r) 28 | globals.lol_client_path = os.path.join(r, files) 29 | lol_settings_path = os.path.join(r, "Config") 30 | return 31 | for r, d, f in os.walk("D:\\"): 32 | for files in f: 33 | if files == "LeagueClient.exe": 34 | print("Successfully found %s" % r) 35 | globals.lol_client_path = os.path.join(r, files) 36 | lol_settings_path = os.path.join(r, "Config") 37 | return 38 | print("Failed to locate League of Legends.") 39 | 40 | 41 | def set_bot_files(): 42 | for files in globals.files_to_replace: 43 | shutil.copy(os.path.join(bot_settings_path, files), os.path.join(lol_settings_path, files)) 44 | print("Successfully loaded bot settings to %s" % lol_settings_path) 45 | 46 | 47 | def get_client_coords(): 48 | hwnd = win32gui.FindWindow(None, 'League of Legends') 49 | rect = win32gui.GetWindowRect(hwnd) 50 | return rect 51 | 52 | 53 | def get_game_coords(): 54 | hwnd = win32gui.FindWindow(None, 'League of Legends (TM) Client') 55 | rect = win32gui.GetWindowRect(hwnd) 56 | return rect 57 | 58 | 59 | def get_riot_client_coords(): 60 | hwnd = win32gui.FindWindow(None, 'Riot Client Main') 61 | rect = win32gui.GetWindowRect(hwnd) 62 | return rect 63 | 64 | 65 | def is_league_in_game(): 66 | try: 67 | find_window(title='League of Legends (TM) Client') 68 | return True 69 | except Exception: 70 | return False 71 | 72 | 73 | def is_client_open(): 74 | try: 75 | find_window(title='League of Legends') 76 | return True 77 | except Exception: 78 | return False 79 | 80 | 81 | def is_riot_client_open(): 82 | try: 83 | find_window(title='Riot Client') 84 | return True 85 | except Exception: 86 | return False 87 | 88 | 89 | def set_status(status): 90 | globals.last_status = status 91 | print(status) 92 | 93 | 94 | def move_windows(): 95 | try: 96 | hwnd = win32gui.FindWindow(None, 'LoL Bot') 97 | win32gui.MoveWindow(hwnd, -8, 0, 655, 1050, True) 98 | # if is_client_open(): 99 | # hwnd = win32gui.FindWindow(None, 'League of Legends') 100 | # win32gui.MoveWindow(hwnd, 640, 180, 1280, 720, True) 101 | # if is_league_in_game(): 102 | # hwnd = win32gui.FindWindow(None, 'League of Legends (TM) Client') 103 | # win32gui.MoveWindow(hwnd, 640, 180, None, None, True) 104 | except Exception: 105 | print("Error: Could not move windows.") 106 | return 107 | 108 | 109 | def focus_game_or_client(): 110 | if is_league_in_game(): 111 | win32gui.SetForegroundWindow(find_window(title='League of Legends (TM) Client')) 112 | elif is_client_open(): 113 | win32gui.SetForegroundWindow(find_window(title='League of Legends')) 114 | 115 | -------------------------------------------------------------------------------- /lol-leveling-bot/bot_settings/game.cfg: -------------------------------------------------------------------------------- 1 | 2 | 3 | [General] 4 | EulaVersionSeen=0 5 | MinimizeCameraMotion=0 6 | EnableScreenShake=1 7 | ThemeMusic=0 8 | ShowCursorLocator=0 9 | GameMouseSpeed=10 10 | EnableCustomAnnouncer=0 11 | EnableAudio=1 12 | UserSetResolution=1 13 | SystemMouseSpeed=0 14 | EnableSoftParticleSupport=1 15 | Antialiasing=0 16 | AlwaysShowExtendedTooltip=0 17 | CursorOverride=0 18 | CursorScale=0.0000 19 | ShowGodray=1 20 | BindSysKeys=0 21 | EnableLeftMouseButtonAttackMove=1 22 | SnapCameraOnRespawn=0 23 | OSXMouseAcceleration=1 24 | EnableTargetedAttackMove=1 25 | TargetChampionsOnlyAsToggle=0 26 | AutoAcquireTarget=0 27 | EnableLightFx=0 28 | WindowMode=1 29 | ShowTurretRangeIndicators=1 30 | HideEyeCandy=0 31 | RelativeTeamColors=1 32 | PredictMovement=0 33 | WaitForVerticalSync=0 34 | Colors=32 35 | Height=720 36 | Width=1280 37 | CfgVersion=10.5.166 38 | 39 | [Sound] 40 | DefaultFXVolume=100 41 | DefaultMusicVolume=100 42 | 43 | [Performance] 44 | GraphicsSlider=2 45 | ShadowsEnabled=1 46 | CharacterInking=1 47 | EnableHUDAnimations=0 48 | EnableParticleOptimizations=0 49 | BudgetOverdrawAverage=10 50 | BudgetSkinnedVertexCount=200000 51 | BudgetSkinnedDrawCallCount=100 52 | BudgetTextureUsage=150000 53 | BudgetVertexCount=500000 54 | BudgetTriangleCount=300000 55 | BudgetDrawCallCount=1000 56 | EnableGrassSwaying=1 57 | EnableFXAA=1 58 | FrameCapType=9 59 | ShadowQuality=1 60 | EffectsQuality=1 61 | GammaEnabled=1 62 | EnvironmentQuality=1 63 | CharacterQuality=2 64 | AutoPerformanceSettings=0 65 | 66 | [HUD] 67 | EternalsMilestoneDisplayMode=0 68 | ShowAllChannelChatSpectator=0 69 | ShowAlliedChat=1 70 | DeathRecapScale=1.0000 71 | ShowPlayerPerks=0 72 | ShowNeutralCamps=1 73 | ObjectTooltips=1 74 | MinimapMoveSelf=1 75 | FlashScreenWhenStunned=1 76 | FlashScreenWhenDamaged=1 77 | DrawHealthBars=1 78 | AutoDisplayTarget=1 79 | ReplayScrollSmoothingEnabled=1 80 | ReplayMiddleMouseScrollSpeed=0.5000 81 | GlobalScaleReplay=1.0000 82 | ItemShopPrevY=90 83 | ItemShopPrevX=315 84 | ShowAllChannelChat=1 85 | ShowTimestamps=1 86 | ShowPlayerStats=1 87 | ShowHealthBarShake=0 88 | ChatScale=100 89 | ItemShopResizeHeight=76 90 | ItemShopResizeWidth=254 91 | ItemShopPrevResizeHeight=720 92 | ItemShopPrevResizeWidth=1280 93 | ItemShopItemDisplayMode=1 94 | ItemShopStartPane=1 95 | GlobalScale=0.4600 96 | MinimapScale=1.0000 97 | PracticeToolScale=1.0000 98 | DisableMouseCaptureDebugger=0 99 | ShowSpellCosts=1 100 | NameTagDisplay=1 101 | ShowChampionIndicator=0 102 | ShowSummonerNames=1 103 | CameraLockMode=1 104 | MiddleClickDragScrollEnabled=0 105 | ScrollSmoothingEnabled=0 106 | KeyboardScrollSpeed=0.5000 107 | MiddleMouseScrollSpeed=0.5000 108 | MapScrollSpeed=0.5000 109 | ShowAttackRadius=1 110 | NumericCooldownFormat=1 111 | EmotePopupUIDisplayMode=2 112 | HideEnemySummonerEmotes=0 113 | DisableHudSpellClick=0 114 | SmartCastWithIndicator_CastWhenNewSpellSelected=0 115 | SmartCastOnKeyRelease=0 116 | EnableLineMissileVis=1 117 | ShowSummonerNamesInScoreboard=0 118 | MirroredScoreboard=0 119 | ShowTeamFramesOnLeft=0 120 | FlipMiniMap=0 121 | 122 | [Chat] 123 | ChatY=-65 124 | ChatX=7 125 | Transparency=0.0000 126 | EnableChatFilter=0 127 | 128 | [Voice] 129 | ActivationSensitivity=0.6500 130 | InputMode=0 131 | InputVolume=1.0000 132 | ShowVoiceChatHalos=1 133 | ShowVoicePanelWithScoreboard=1 134 | 135 | [FloatingText] 136 | Debug_Enabled=1 137 | ShieldBonusDamage_Enabled=1 138 | ScoreProject1_Enabled=1 139 | ScoreProject0_Enabled=1 140 | ScoreDarkStar_Enabled=1 141 | PracticeToolDPS_Enabled=1 142 | PracticeToolLastHit_Enabled=1 143 | PracticeToolTotal_Enabled=1 144 | Absorbed_Enabled=1 145 | OMW_Enabled=1 146 | Countdown_Enabled=1 147 | EnemyTrueDamageCritical_Enabled=1 148 | EnemyMagicalDamageCritical_Enabled=1 149 | EnemyPhysicalDamageCritical_Enabled=1 150 | EnemyTrueDamage_Enabled=1 151 | EnemyMagicalDamage_Enabled=1 152 | EnemyPhysicalDamage_Enabled=1 153 | TrueDamage_Enabled=1 154 | MagicalDamage_Enabled=1 155 | PhysicalDamage_Enabled=1 156 | Score_Enabled=1 157 | QuestComplete_Enabled=1 158 | QuestReceived_Enabled=1 159 | Disable_Enabled=1 160 | Level_Enabled=1 161 | Gold_Enabled=1 162 | Experience_Enabled=1 163 | TrueDamageCritical_Enabled=1 164 | MagicalDamageCritical_Enabled=1 165 | PhysicalDamageCritical_Enabled=1 166 | Dodge_Enabled=1 167 | ManaDamage_Enabled=1 168 | ManaHeal_Enabled=1 169 | Heal_Enabled=1 170 | Special_Enabled=1 171 | Invulnerable_Enabled=1 172 | 173 | [MapSkinOptions] 174 | MapSkinOptionDisable10Year=1 175 | MapSkinOptionDisableArcade=1 176 | MapSkinOptionDisableAprilFools2019=1 177 | MapSkinOptionDisableSnowdown=1 178 | MapSkinOptionDisableOdyssey=1 179 | 180 | [Volume] 181 | VoiceMute=0 182 | SfxMute=0 183 | PingsMute=0 184 | MusicMute=0 185 | MasterMute=0 186 | AnnouncerMute=0 187 | AmbienceMute=0 188 | PingsVolume=0.2700 189 | VoiceVolume=0.2900 190 | AmbienceVolume=0.2700 191 | SfxVolume=0.3000 192 | MasterVolume=0.00 193 | MusicVolume=0.0000 194 | AnnouncerVolume=0.2800 195 | 196 | [Replay] 197 | EnableDirectedCamera=0 198 | EnableHelpTip=0 199 | 200 | [RecommendPage] 201 | Khazix_SR_CLASSIC=riot[Recommended] 202 | Ezreal_SR_CLASSIC=riot[Recommended] 203 | Rengar_SR_CLASSIC=riot[Recommended] 204 | 205 | [ColorPalette] 206 | ColorPalette=0 207 | 208 | [LossOfControl] 209 | ShowSlows=0 210 | LossOfControlEnabled=1 211 | 212 | [TFTChat] 213 | ChatY=276 214 | ChatX=0 215 | 216 | [TFTHUD] 217 | EnableChat=1 218 | 219 | 220 | [Accessibility] 221 | ColorContrast=0.5000 222 | ColorBrightness=0.5000 223 | ColorGamma=0.5000 224 | ColorLevel=0.5000 -------------------------------------------------------------------------------- /lol-leveling-bot/bot_settings/input.ini: -------------------------------------------------------------------------------- 1 | 2 | 3 | [Quickbinds] 4 | evtCastSpell4smart=1 5 | evtCastSpell3smart=1 6 | evtCastSpell2smart=1 7 | evtCastSpell1smart=1 8 | evtCastAvatarSpell2smart=1 9 | evtCastAvatarSpell1smart=1 10 | evtUseItem4smart=1 11 | evtUseItem5smart=1 12 | evtUseItem6smart=1 13 | evtUseItem1smart=1 14 | evtUseItem2smart=1 15 | evtUseItem3smart=1 16 | evtUseVisionItemsmart=1 17 | 18 | [GameEvents] 19 | evtUseItem7=[b] 20 | evtUseItem5=[6] 21 | evtUseItem4=[5] 22 | evtUseItem3=[3] 23 | evtUseItem1=[1] 24 | evtToggleMinionHealthBars= 25 | evtSysMenu=[Esc] 26 | evtSmartPlusSelfCastWithIndicatorVisionItem= 27 | evtSmartPlusSelfCastWithIndicatorSpell4= 28 | evtSmartPlusSelfCastWithIndicatorSpell3= 29 | evtSmartPlusSelfCastWithIndicatorSpell2= 30 | evtSmartPlusSelfCastWithIndicatorSpell1= 31 | evtSmartPlusSelfCastWithIndicatorItem6= 32 | evtSmartPlusSelfCastWithIndicatorItem5= 33 | evtSmartPlusSelfCastWithIndicatorItem4= 34 | evtSmartPlusSelfCastWithIndicatorItem3= 35 | evtSmartPlusSelfCastWithIndicatorItem2= 36 | evtSmartPlusSelfCastWithIndicatorItem1= 37 | evtSmartPlusSelfCastWithIndicatorAvatarSpell2= 38 | evtSmartPlusSelfCastWithIndicatorAvatarSpell1= 39 | evtSmartPlusSelfCastVisionItem= 40 | evtSmartPlusSelfCastSpell4= 41 | evtSmartPlusSelfCastSpell3= 42 | evtSmartPlusSelfCastSpell2= 43 | evtSmartPlusSelfCastSpell1= 44 | evtSmartPlusSelfCastItem6= 45 | evtSmartPlusSelfCastItem5= 46 | evtSmartPlusSelfCastItem4= 47 | evtSmartPlusSelfCastItem3= 48 | evtSmartPlusSelfCastItem2= 49 | evtSmartPlusSelfCastItem1= 50 | evtSmartPlusSelfCastAvatarSpell2= 51 | evtSmartPlusSelfCastAvatarSpell1= 52 | evtSmartCastWithIndicatorVisionItem= 53 | evtSmartCastWithIndicatorSpell4= 54 | evtSmartCastWithIndicatorSpell3= 55 | evtSmartCastWithIndicatorSpell2= 56 | evtSmartCastWithIndicatorSpell1= 57 | evtSmartCastWithIndicatorItem6= 58 | evtSmartCastWithIndicatorItem5= 59 | evtSmartCastWithIndicatorItem4= 60 | evtSmartCastWithIndicatorItem3= 61 | evtSmartCastWithIndicatorItem2= 62 | evtSmartCastWithIndicatorItem1= 63 | evtSmartCastWithIndicatorAvatarSpell2= 64 | evtSmartCastWithIndicatorAvatarSpell1= 65 | evtSmartCastVisionItem=[Shift][4] 66 | evtSmartCastSpell4=[Shift][r] 67 | evtSmartCastSpell3=[Shift][e] 68 | evtSmartCastSpell2=[Shift][w] 69 | evtSmartCastSpell1=[Shift][q] 70 | evtSmartCastItem6=[Shift][7] 71 | evtSmartCastItem5=[Shift][6] 72 | evtSmartCastItem4=[Shift][5] 73 | evtSmartCastItem3=[Shift][3] 74 | evtSmartCastItem2=[Shift][2] 75 | evtSmartCastItem1=[Shift][1] 76 | evtSmartCastAvatarSpell2=[Shift][f] 77 | evtSmartCastAvatarSpell1=[Shift][d] 78 | evtShowVoicePanel=[m] 79 | evtShowSummonerNames= 80 | evtShowScoreBoard=[o] 81 | evtShowHealthBars= 82 | evtShowCharacterMenu=[c] 83 | evtSelfCastVisionItem=[Alt][4] 84 | evtSelfCastItem6=[Alt][7] 85 | evtSelfCastItem5=[Alt][6] 86 | evtSelfCastItem4=[Alt][5] 87 | evtSelfCastItem3=[Alt][3] 88 | evtSelfCastItem2=[Alt][2] 89 | evtSelfCastItem1=[Alt][1] 90 | evtSelfCastAvatarSpell2=[Alt][f], 91 | evtSelfCastAvatarSpell1=[Alt][d], 92 | evtSelectSelf=[] 93 | evtSelectAlly4=[F4] 94 | evtSelectAlly3=[F3] 95 | evtSelectAlly2=[F2] 96 | evtSelectAlly1=[F1] 97 | evtScrollUp=[Up Arrow] 98 | evtScrollRight=[Right Arrow] 99 | evtScrollLeft=[Left Arrow] 100 | evtScrollDown=[Down Arrow] 101 | evtRadialEmotePlaySlot4= 102 | evtRadialEmotePlaySlot3= 103 | evtRadialEmotePlaySlot2= 104 | evtRadialEmotePlaySlot1= 105 | evtRadialEmotePlaySlot0= 106 | evtRadialEmoteOpen= 107 | evtRadialEmoteInstantOpen=[t] 108 | evtPushToTalk=[] 109 | evtPlayerPingRadialDanger= 110 | evtPlayerPingOMW= 111 | evtPlayerPingMIA=[Button 5] 112 | evtPlayerPingComeHere= 113 | evtPlayerPingAreaIsWarded=[x] 114 | evtPlayerMoveClick=[Button 2],[Shift][Button 2] 115 | evtPlayerAttackOnlyClick= 116 | evtPlayerAttackMoveClick=[Button 2] 117 | evtPetMoveClick=[Alt][Button 2],[Ctrl][Button 2] 118 | evtOnUIMouse4Pan=[] 119 | evtNormalCastVisionItem= 120 | evtNormalCastSpell4= 121 | evtNormalCastSpell3= 122 | evtNormalCastSpell2= 123 | evtNormalCastSpell1= 124 | evtNormalCastItem6= 125 | evtNormalCastItem5= 126 | evtNormalCastItem4= 127 | evtNormalCastItem3= 128 | evtNormalCastItem2= 129 | evtNormalCastItem1= 130 | evtNormalCastAvatarSpell2= 131 | evtNormalCastAvatarSpell1= 132 | evtEmoteToggle=[Ctrl][5] 133 | evtEmoteTaunt=[Ctrl][2] 134 | evtEmoteLaugh=[Ctrl][4] 135 | evtEmoteJoke=[Ctrl][1] 136 | evtEmoteDance=[k],[l] 137 | evtDrawHud= 138 | evtDragScrollLock= 139 | evtChatHistory=[z] 140 | evtChampMasteryDisplay=[] 141 | evtCastSpell4=[r] 142 | evtCastSpell3=[e] 143 | evtCastSpell2=[w] 144 | evtCastSpell1=[q] 145 | evtCastAvatarSpell2=[f] 146 | evtCastAvatarSpell1=[d] 147 | evtCameraSnap=[Space] 148 | evtCameraLockToggle=[y] 149 | evntPlayerPingDanger=[Ctrl][Button 1] 150 | evntPlayerPingCursorDanger=[v] 151 | evntPlayerPing=[Alt][Button 1] 152 | evtSelfCastSpell1=[] 153 | evtPlayerAttackMove=[4],[] 154 | evtChampionOnly=[Button 4] 155 | evtSelfCastSpell3=[] 156 | evtUseItem6=[7] 157 | evtUseItem2=[s] 158 | evtPlayerHoldPosition=[a] 159 | evtPlayerStopPosition=[] 160 | evtOpenShop=[`] 161 | evtSelfCastSpell4=[] 162 | evtSelfCastSpell2=[] 163 | evtLevelSpell2=[Alt][w] 164 | evtLevelSpell3=[Alt][e] 165 | evtLevelSpell1=[Alt][q] 166 | evntPlayerPingCursor=[] 167 | evtLevelSpell4=[Alt][r] 168 | evtUseVisionItem=[g] 169 | 170 | [HUDEvents] 171 | evtOnUIMouse1=[Button 1],[Shift][Button 1] 172 | evntHudMoveableSelect=[Button 1],[Shift][Button 1] 173 | evtTogglePlayerStats=[Ctrl][c] 174 | evtToggleMouseClip=[F9] 175 | evtToggleFPSAndLatency=[Ctrl][f] 176 | evtHoldShowScoreBoard=[Tab] 177 | 178 | [ShopEvents] 179 | evtShopSwitchTabs=[Ctrl][Tab] 180 | evtShopFocusSearch=[Ctrl][l],[Ctrl][Return] -------------------------------------------------------------------------------- /lol-leveling-bot/robot.py: -------------------------------------------------------------------------------- 1 | import subprocess 2 | import time 3 | from timeit import default_timer as timer 4 | 5 | from pywinauto.findwindows import find_window 6 | 7 | import globals 8 | import utilities 9 | import pictures 10 | import regions 11 | import listener 12 | 13 | import psutil 14 | import pyautogui 15 | import win32api 16 | import win32con 17 | import win32gui 18 | import os 19 | 20 | # Champion variables 21 | list_of_champs = [pictures.ashe, pictures.annie] 22 | 23 | 24 | def run(): 25 | utilities.set_status('Starting bot...') 26 | 27 | # If league is already in game, finish the game 28 | if utilities.is_league_in_game(): 29 | complete_game() 30 | 31 | # Otherwise, restart client and wait for login 32 | else: 33 | restart_client() 34 | utilities.set_status('Awaiting login...') 35 | await_login() 36 | 37 | # Start queueing up 38 | globals.time_since_last_click = timer() 39 | utilities.set_status('Queueing for a game...') 40 | 41 | # Put the console on the left side of the screen 42 | utilities.move_windows() 43 | 44 | # Start loop 45 | while True: 46 | pause_if_needed() 47 | 48 | # If game has started, complete the game 49 | if utilities.is_league_in_game(): 50 | complete_game() 51 | continue 52 | 53 | # Check for daily play rewards 54 | if attempt_to_click_on(pictures.daily_play, None, click=False): 55 | daily_play() 56 | 57 | # Check for level up rewards 58 | attempt_to_click_on(pictures.ok, None) 59 | 60 | # Check for clash notification 61 | attempt_to_click_on(pictures.clash, None) 62 | 63 | # Check if champ select bugged 64 | attempt_to_click_on(pictures.ok_champ_select_bug, None) 65 | 66 | # Check if we're in champ select 67 | if attempt_to_click_on(pictures.choose_champ, regions.choose_champ, click=False): 68 | champ_select() 69 | 70 | # Check for level 30 71 | if attempt_to_click_on(pictures.level_30, None, click=False): 72 | utilities.set_status("The account has reached level 30!") 73 | stop_bot() 74 | 75 | # Check for key fragment popups 76 | attempt_to_click_on(pictures.key_fragment, None) 77 | 78 | # Check for other buttons 79 | attempt_to_click_on(pictures.play_button, regions.play_button) 80 | attempt_to_click_on(pictures.party, regions.party_button) 81 | attempt_to_click_on(pictures.coop_vs_ai, regions.coop_vs_ai) 82 | attempt_to_click_on(pictures.intermediate_bots, regions.intermediate_bots) 83 | attempt_to_click_on(pictures.confirm, regions.confirm) 84 | attempt_to_click_on(pictures.find_match, regions.find_match) 85 | attempt_to_click_on(pictures.accept, regions.accept) 86 | attempt_to_click_on(pictures.play_again, None) 87 | attempt_to_click_on(pictures.continue_btn, None) 88 | 89 | # If 2 minutes has elapsed without doing anything, restart client 90 | if did_timeout(120): 91 | client_stuck() 92 | 93 | 94 | def complete_game(): 95 | utilities.set_status('Waiting for game to start...') 96 | 97 | # Wait until recall button is visible, then we know we're in game 98 | while not attempt_to_click_on(pictures.recall, None, is_game=True, click=False): 99 | pause_if_needed() 100 | 101 | # Click mid 102 | utilities.set_status('Running it down mid...') 103 | while True: 104 | pause_if_needed() 105 | 106 | # If we're out of game 107 | if not utilities.is_league_in_game(): 108 | break 109 | 110 | # If the camera isn't locked, lock it 111 | if attempt_to_click_on(pictures.lock_camera, None, is_game=True, click=False): 112 | lock_screen() 113 | 114 | # Get the location of league window 115 | try: 116 | rect = utilities.get_game_coords() 117 | except Exception: 118 | continue 119 | x = rect[0] + 1260 120 | y = rect[1] + 592 121 | 122 | # Right click down mid every 3 seconds 123 | try: 124 | win32api.SetCursorPos((x, y)) 125 | win32api.mouse_event(win32con.MOUSEEVENTF_RIGHTDOWN, x, y, 0, 0) 126 | win32api.mouse_event(win32con.MOUSEEVENTF_RIGHTUP, x, y, 0, 0) 127 | time.sleep(3) 128 | except Exception: 129 | continue 130 | 131 | # Once the game is finished 132 | increment_games() 133 | 134 | # Skip honor 135 | globals.time_since_last_click = timer() 136 | while not attempt_to_click_on(pictures.skip_honor, None): 137 | if did_timeout(30): 138 | client_stuck() 139 | return 140 | time.sleep(1) 141 | 142 | # Requeue for another game 143 | utilities.set_status("Queueing for a game...") 144 | 145 | 146 | def attempt_to_click_on(picture, region, is_game=False, is_riot_client=False, click=True, conf=0.95, delay=True): 147 | if not globals.go_flag: 148 | return False 149 | picture = os.path.join(globals.picture_path, picture) 150 | try: 151 | if is_game: 152 | rect = utilities.get_game_coords() 153 | elif is_riot_client: 154 | rect = utilities.get_riot_client_coords() 155 | else: 156 | rect = utilities.get_client_coords() 157 | if region is not None: 158 | start_x = rect[0] + region[0] 159 | start_y = rect[1] + region[1] 160 | width = region[2] - region[0] 161 | height = region[3] - region[1] 162 | rect = (start_x, start_y, width, height) 163 | coordinates = pyautogui.locateCenterOnScreen(picture, region=rect, confidence=conf) 164 | if coordinates is not None: 165 | if click: 166 | pyautogui.click(coordinates[0], coordinates[1]) 167 | globals.time_since_last_click = timer() 168 | if delay: 169 | time.sleep(1) 170 | return True 171 | except Exception: 172 | return False 173 | 174 | 175 | def did_timeout(seconds): 176 | if timer() - globals.time_since_last_click > seconds: 177 | return True 178 | else: 179 | return False 180 | 181 | 182 | def champ_select(): 183 | for champion in list_of_champs: 184 | if attempt_to_click_on(champion, regions.champ_select): 185 | time.sleep(2) 186 | if attempt_to_click_on(pictures.lockin, regions.lockin): 187 | return True 188 | else: 189 | return False 190 | return False 191 | 192 | 193 | def client_stuck(): 194 | utilities.set_status('Bot stuck. Rebooting...') 195 | restart_client() 196 | utilities.set_status('Awaiting login...') 197 | await_login() 198 | globals.time_since_last_click = timer() 199 | utilities.set_status('Queueing for a game...') 200 | 201 | 202 | def await_login(): 203 | while True: 204 | pause_if_needed() 205 | if attempt_to_click_on(pictures.play_button, regions.play_button): 206 | return 207 | elif attempt_to_click_on(pictures.party, regions.party_button): 208 | return 209 | elif attempt_to_click_on(pictures.daily_play, None): 210 | daily_play() 211 | return 212 | elif utilities.is_league_in_game(): 213 | complete_game() 214 | return 215 | elif attempt_to_click_on(pictures.riot_client_play, None, is_riot_client=True): 216 | pass 217 | 218 | 219 | def lock_screen(): 220 | try: 221 | rect = utilities.get_game_coords() 222 | x, y = regions.game_lockscreen_coords 223 | x = rect[0] + x 224 | y = rect[1] + y 225 | win32api.SetCursorPos((x, y)) 226 | win32api.mouse_event(win32con.MOUSEEVENTF_LEFTDOWN, x, y, 0, 0) 227 | time.sleep(0.2) 228 | win32api.mouse_event(win32con.MOUSEEVENTF_LEFTUP, x, y, 0, 0) 229 | time.sleep(0.2) 230 | except Exception: 231 | pass 232 | 233 | 234 | def open_client(): 235 | try: 236 | subprocess.Popen(globals.lol_client_path) 237 | except Exception: 238 | print("Couldn't open league client") 239 | stop_bot() 240 | 241 | 242 | def restart_client(): 243 | if utilities.is_client_open(): 244 | utilities.set_status('Restarting client...') 245 | try: 246 | for proc in psutil.process_iter(): 247 | if proc.name() == "LeagueClient.exe": 248 | proc.kill() 249 | break 250 | except Exception as e: 251 | print(e) 252 | while utilities.is_client_open(): 253 | time.sleep(1) 254 | else: 255 | utilities.set_status('Starting client...') 256 | open_client() 257 | 258 | 259 | def daily_play(): 260 | print("Claiming daily play rewards...") 261 | done = False 262 | while not done: 263 | if not globals.go_flag: 264 | globals.time_since_last_click = timer() 265 | time.sleep(1) 266 | continue 267 | # If we don't find anything within 30 seconds, the client is probably stuck 268 | if did_timeout(30): 269 | client_stuck() 270 | attempt_to_click_on(pictures.daily_play_caitlyn, None) 271 | attempt_to_click_on(pictures.daily_play_illaoi, None) 272 | attempt_to_click_on(pictures.daily_play_ziggs, None) 273 | attempt_to_click_on(pictures.daily_play_thresh, None) 274 | attempt_to_click_on(pictures.daily_play_ekko, None) 275 | attempt_to_click_on(pictures.select_daily, None) 276 | done = attempt_to_click_on(pictures.ok_daily, None) 277 | return 278 | 279 | 280 | def increment_games(): 281 | globals.number_of_games_finished = globals.number_of_games_finished + 1 282 | utilities.set_status("The bot has finished %d games." % globals.number_of_games_finished) 283 | 284 | 285 | def set_to_pause(): 286 | if globals.go_flag == 0: 287 | globals.go_flag = 1 288 | utilities.set_status(globals.last_status) 289 | else: 290 | globals.go_flag = 0 291 | print("Bot paused.") 292 | 293 | 294 | def pause_if_needed(): 295 | while not globals.go_flag: 296 | time.sleep(1) 297 | globals.time_since_last_click = timer() 298 | 299 | 300 | def stop_bot(): 301 | listener.stop() 302 | print("Bot has terminated.") 303 | while True: 304 | time.sleep(3) 305 | --------------------------------------------------------------------------------