Skip to content

Commit 5f406fe

Browse files
committed
fix: click bug #256 and directory bug #258
1 parent 41588c8 commit 5f406fe

File tree

2 files changed

+71
-45
lines changed

2 files changed

+71
-45
lines changed

lolbot/bot/bot.py

+66-40
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313

1414
import pyautogui
1515

16-
from lolbot.bot import game, launcher, logger, window
16+
from lolbot.bot import game, launcher, logger, window, controller
1717
from lolbot.common import accounts, config, proc
1818
from lolbot.lcu.lcu_api import LCUApi, LCUError
1919

@@ -31,19 +31,21 @@
3131

3232
class BotError(Exception):
3333
"""Indicates the League Client instance should be restarted."""
34+
3435
pass
3536

3637

3738
class Bot:
3839
"""Handles the League Client and all tasks needed to start a new game."""
40+
3941
def __init__(self) -> None:
4042
self.api = LCUApi()
4143
self.config = config.load_config()
42-
self.league_dir = self.config['league_dir']
43-
self.max_level = self.config['max_level']
44-
self.lobby = self.config['lobby']
45-
self.champs = self.config['champs']
46-
self.dialog = self.config['dialog']
44+
self.league_dir = self.config["league_dir"]
45+
self.max_level = self.config["max_level"]
46+
self.lobby = self.config["lobby"]
47+
self.champs = self.config["champs"]
48+
self.dialog = self.config["dialog"]
4749
self.account = None
4850
self.phase = None
4951
self.prev_phase = None
@@ -62,7 +64,9 @@ def run(self, message_queue: mp.Queue, games: mp.Value, errors: mp.Value) -> Non
6264
try:
6365
errors.value = self.bot_errors
6466
self.account = accounts.get_account(self.max_level)
65-
launcher.launch_league(self.account['username'], self.account['password'])
67+
launcher.launch_league(
68+
self.account["username"], self.account["password"]
69+
)
6670
self.leveling_loop(games)
6771
proc.close_all_processes()
6872
self.bot_errors = 0
@@ -93,23 +97,23 @@ def leveling_loop(self, games: mp.Value) -> None:
9397
"""Loop that takes action based on the phase of the League Client, continuously starts games."""
9498
while not self.account_leveled():
9599
match self.get_phase():
96-
case 'None' | 'Lobby':
100+
case "None" | "Lobby":
97101
self.start_matchmaking()
98-
case 'Matchmaking':
102+
case "Matchmaking":
99103
self.queue()
100-
case 'ReadyCheck':
104+
case "ReadyCheck":
101105
self.accept_match()
102-
case 'ChampSelect':
106+
case "ChampSelect":
103107
self.champ_select()
104-
case 'InProgress':
108+
case "InProgress":
105109
game.play_game()
106-
case 'Reconnect':
110+
case "Reconnect":
107111
self.reconnect()
108-
case 'WaitingForStats':
112+
case "WaitingForStats":
109113
self.wait_for_stats()
110-
case 'PreEndOfGame':
114+
case "PreEndOfGame":
111115
self.pre_end_of_game()
112-
case 'EndOfGame':
116+
case "EndOfGame":
113117
self.end_of_game()
114118
games.value += 1
115119
case _:
@@ -122,7 +126,11 @@ def get_phase(self) -> str:
122126
try:
123127
self.prev_phase = self.phase
124128
self.phase = self.api.get_phase()
125-
if self.prev_phase == self.phase and self.phase != "Matchmaking" and self.phase != 'ReadyCheck':
129+
if (
130+
self.prev_phase == self.phase
131+
and self.phase != "Matchmaking"
132+
and self.phase != "ReadyCheck"
133+
):
126134
self.phase_errors += 1
127135
if self.phase_errors == MAX_PHASE_ERRORS:
128136
raise BotError("Transition error. Phase will not change")
@@ -173,7 +181,7 @@ def queue(self) -> None:
173181
start = datetime.now()
174182
while True:
175183
try:
176-
if self.api.get_phase() != 'Matchmaking':
184+
if self.api.get_phase() != "Matchmaking":
177185
return
178186
elif datetime.now() - start > timedelta(minutes=15):
179187
raise BotError("Queue Timeout")
@@ -201,13 +209,21 @@ def champ_select(self) -> None:
201209
except LCUError:
202210
return
203211
try:
204-
for action in data['actions'][0]:
205-
if action['actorCellId'] == data['localPlayerCellId']:
206-
if action['championId'] == 0: # No champ hovered. Hover a champion.
212+
for action in data["actions"][0]:
213+
if action["actorCellId"] == data["localPlayerCellId"]:
214+
if (
215+
action["championId"] == 0
216+
): # No champ hovered. Hover a champion.
207217
champ_index += 1
208-
self.api.hover_champion(action['id'], champ_list[champ_index])
209-
elif not action['completed']: # Champ is hovered but not locked in.
210-
self.api.lock_in_champion(action['id'], action['championId'])
218+
self.api.hover_champion(
219+
action["id"], champ_list[champ_index]
220+
)
221+
elif not action[
222+
"completed"
223+
]: # Champ is hovered but not locked in.
224+
self.api.lock_in_champion(
225+
action["id"], action["championId"]
226+
)
211227
else: # Champ is locked in. Nothing left to do.
212228
sleep(2)
213229
except LCUError:
@@ -223,15 +239,15 @@ def reconnect(self) -> None:
223239
return
224240
except LCUError:
225241
sleep(2)
226-
log.warning('Could not reconnect to game')
242+
log.warning("Could not reconnect to game")
227243

228244
def wait_for_stats(self) -> None:
229245
"""Waits for the League Client Phase to change to something other than 'WaitingForStats'."""
230246
log.info("Waiting for stats")
231247
for i in range(60):
232248
sleep(2)
233249
try:
234-
if self.api.get_phase() != 'WaitingForStats':
250+
if self.api.get_phase() != "WaitingForStats":
235251
return
236252
except LCUError:
237253
pass
@@ -242,14 +258,22 @@ def pre_end_of_game(self) -> None:
242258
log.info("Honoring teammates and accepting rewards")
243259
sleep(3)
244260
try:
245-
proc.click(POPUP_SEND_EMAIL_X_RATIO, proc.LEAGUE_CLIENT_WINNAME, 2)
261+
controller.left_click(
262+
POPUP_SEND_EMAIL_X_RATIO, proc.LEAGUE_CLIENT_WINNAME, 2
263+
)
246264
if not self.honor_player():
247265
sleep(60) # Honor failed for some reason, wait out the honor screen
248-
proc.click(POPUP_SEND_EMAIL_X_RATIO, proc.LEAGUE_CLIENT_WINNAME, 2)
266+
controller.left_click(
267+
POPUP_SEND_EMAIL_X_RATIO, proc.LEAGUE_CLIENT_WINNAME, 2
268+
)
249269
for i in range(3):
250-
proc.click(POST_GAME_SELECT_CHAMP_RATIO, proc.LEAGUE_CLIENT_WINNAME, 1)
251-
proc.click(POST_GAME_OK_RATIO, proc.LEAGUE_CLIENT_WINNAME, 1)
252-
proc.click(POPUP_SEND_EMAIL_X_RATIO, proc.LEAGUE_CLIENT_WINNAME, 1)
270+
controller.left_click(
271+
POST_GAME_SELECT_CHAMP_RATIO, proc.LEAGUE_CLIENT_WINNAME, 1
272+
)
273+
controller.left_click(POST_GAME_OK_RATIO, proc.LEAGUE_CLIENT_WINNAME, 1)
274+
controller.left_click(
275+
POPUP_SEND_EMAIL_X_RATIO, proc.LEAGUE_CLIENT_WINNAME, 1
276+
)
253277
except (window.WindowNotFound, pyautogui.FailSafeException):
254278
sleep(3)
255279

@@ -259,12 +283,12 @@ def honor_player(self) -> bool:
259283
try:
260284
players = self.api.get_players_to_honor()
261285
index = random.randint(0, len(players) - 1)
262-
self.api.honor_player(players[index]['summonerId'])
286+
self.api.honor_player(players[index]["summonerId"])
263287
sleep(2)
264288
return True
265289
except LCUError as e:
266290
log.warning(e)
267-
log.warning('Honor Failure')
291+
log.warning("Honor Failure")
268292
return False
269293

270294
def end_of_game(self) -> None:
@@ -273,7 +297,7 @@ def end_of_game(self) -> None:
273297
posted = False
274298
for i in range(15):
275299
try:
276-
if self.api.get_phase() != 'EndOfGame':
300+
if self.api.get_phase() != "EndOfGame":
277301
return
278302
if not posted:
279303
self.api.play_again()
@@ -289,8 +313,8 @@ def account_leveled(self) -> bool:
289313
"""Checks if account has reached max level."""
290314
try:
291315
if self.api.get_summoner_level() >= self.max_level:
292-
if self.account['username'] == self.api.get_display_name():
293-
self.account['level'] = self.max_level
316+
if self.account["username"] == self.api.get_display_name():
317+
self.account["level"] = self.max_level
294318
accounts.save_or_add(self.account)
295319
log.info("Account successfully leveled")
296320
return True
@@ -312,23 +336,25 @@ def wait_for_patching(self) -> None:
312336
def set_game_config(self) -> None:
313337
"""Overwrites the League of Legends game config."""
314338
log.info("Overwriting game configs")
315-
path = self.league_dir + '/Config/game.cfg'
339+
path = self.league_dir + "/Config/game.cfg"
316340
folder = os.path.abspath(os.path.join(path, os.pardir))
317341
for filename in os.listdir(folder):
318342
file_path = os.path.join(folder, filename)
319343
try:
320344
if os.path.isfile(file_path) or os.path.islink(file_path):
321345
os.unlink(file_path)
322346
except Exception as e:
323-
log.error('Failed to delete %s. Reason: %s' % (file_path, e))
347+
log.error("Failed to delete %s. Reason: %s" % (file_path, e))
324348
shutil.copy(proc.resource_path(config.GAME_CFG), path)
325349

326350
@staticmethod
327351
def print_ascii() -> None:
328352
"""Prints some League ascii art."""
329-
print("""\n\n
353+
print(
354+
"""\n\n
330355
──────▄▌▐▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▌
331356
───▄▄██▌█ BEEP BEEP
332357
▄▄▄▌▐██▌█ -15 LP DELIVERY
333358
███████▌█▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▌
334-
▀(⊙)▀▀▀▀▀▀▀(⊙)(⊙)▀▀▀▀▀▀▀▀▀▀(⊙)\n\n\t\t\t\tLoL Bot\n\n""")
359+
▀(⊙)▀▀▀▀▀▀▀(⊙)(⊙)▀▀▀▀▀▀▀▀▀▀(⊙)\n\n\t\t\t\tLoL Bot\n\n"""
360+
)

lolbot/common/config.py

+5-5
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,15 @@
55
import os
66
import json
77

8-
if os.name == 'nt':
9-
CONFIG_DIR = os.path.join(os.getenv('LOCALAPPDATA'), 'LoLBot')
10-
else:
11-
CONFIG_DIR = os.path.join(os.path.expanduser('~'), 'Library', 'Application Support', 'LoLBot')
12-
8+
CONFIG_DIR = os.path.join(os.getenv('LOCALAPPDATA'), 'LoLBot')
139
os.makedirs(CONFIG_DIR, exist_ok=True)
1410

1511
BAK_DIR = os.path.join(CONFIG_DIR, 'bak')
12+
os.makedirs(BAK_DIR, exist_ok=True)
13+
1614
LOG_DIR = os.path.join(CONFIG_DIR, 'logs')
15+
os.makedirs(LOG_DIR, exist_ok=True)
16+
1717
CONFIG_PATH = os.path.join(CONFIG_DIR, 'config.json')
1818
ACCOUNT_PATH = os.path.join(CONFIG_DIR, 'accounts.json')
1919

0 commit comments

Comments
 (0)