diff --git a/src/model/bot.py b/src/model/bot.py index 410233aa..65142fb1 100644 --- a/src/model/bot.py +++ b/src/model/bot.py @@ -11,6 +11,7 @@ from abc import ABC, abstractmethod from enum import Enum from typing import List, Union +from random import uniform, choice import customtkinter import numpy as np @@ -27,6 +28,7 @@ from utilities.mouse import Mouse from utilities.options_builder import OptionsBuilder from utilities.window import Window, WindowInitializationError +from utilities import constants warnings.filterwarnings("ignore", category=UserWarning) @@ -596,3 +598,24 @@ def toggle_run(self, toggle_on: bool): self.mouse.click() else: self.log_msg("Run is already off.") + def check_skill_xp(self, skill: str, min_hover_time: float = 8.0, max_hover_time: float = 35.0): + """This method will hover over a skill in the skills tab to emulate a human checking the XP left for the training skill. + + Args: + skill (str): Name of skill to check + min_hover_time (float, optional): Minimum amount of time in seconds to hover on the skill. Defaults to 8.0. + max_hover_time (float, optional): Maximum amount of time in seconds to hover on the skill. Defaults to 35.0. + """ + skill = skill.lower() + sleep_time = uniform(min_hover_time, max_hover_time) + if skill not in constants.SKILL_TAB_MAP.keys(): + self.log_msg(f"[WARNING] Skill specified: {skill} is not in skill list. Using random skill to hover") + skill = choice(constants.SKILL_TAB_MAP.keys()) + self.log_msg(f"Opening skill tab and checking {skill} skill and hovering for: {sleep_time}s..") + self.mouse.move_to(self.win.cp_tabs[constants.INVENTORY_TAB_SKILL].random_point()) # Open Skill tab + self.mouse.click() + self.mouse.move_to(self.win.skill_slots[constants.SKILL_TAB_MAP[skill]].random_point()) # hover on selected skill + time.sleep(sleep_time) + self.log_msg("Selecting inventory...") + self.mouse.move_to(self.win.cp_tabs[constants.INVENTORY_TAB_INVENTORY].random_point()) + self.mouse.click() diff --git a/src/utilities/constants.py b/src/utilities/constants.py new file mode 100644 index 00000000..543c7904 --- /dev/null +++ b/src/utilities/constants.py @@ -0,0 +1,175 @@ +# Inventory Tab Definitions + +INVENTORY_TAB_COMBAT = 0 +INVENTORY_TAB_SKILL = 1 +INVENTORY_TAB_QUEST = 2 +INVENTORY_TAB_INVENTORY = 3 +INVENTORY_TAB_EQUIPMENT = 4 +INVENTORY_TAB_PRAYER = 5 +INVENTORY_TAB_MAGIC = 6 +INVENTORY_TAB_CLAN_CHAT = 7 +INVENTORY_TAB_FRIENDS_LIST = 8 +INVENTORY_TAB_ACCOUNT_MANAGEMENT = 9 +INVENTORY_TAB_LOGOUT = 10 +INVENTORY_TAB_SETTINGS = 11 +INVENTORY_TAB_EMOTES = 12 +INVENTORY_TAB_MUSIC = 13 + +# Magic tab spell definitions + +MAGIC_TAB_HOME_TELEPORT = 0 +MAGIC_TAB_WIND_STRIKE = 1 +MAGIC_TAB_CONFUSE = 2 +MAGIC_TAB_ENCHANT_CROSSBOW_BOLT = 3 +MAGIC_TAB_WATER_STRIKE = 4 +MAGIC_TAB_LEVEL_ONE_ENCHANT = 5 +MAGIC_TAB_EARTH_STRIKE = 6 +MAGIC_TAB_WEAKEN = 7 +MAGIC_TAB_FIRE_STRIKE = 8 +MAGIC_TAB_BONES_TO_BANANAS = 9 +MAGIC_TAB_WIND_BOLT = 10 +MAGIC_TAB_CURSE = 11 +MAGIC_TAB_BIND = 12 +MAGIC_TAB_LOW_LEVEL_ALCHEMY = 13 +MAGIC_TAB_WATER_BOLT = 14 +MAGIC_TAB_VARROCK_TELEPORT = 15 +MAGIC_TAB_LEVEL_TWO_ENCHANT = 16 +MAGIC_TAB_EARTH_BOLT = 17 +MAGIC_TAB_LUMBRIDGE_TELEPORT = 18 +MAGIC_TAB_TELEKINETIC_GRAB = 19 +MAGIC_TAB_FIRE_BOLT = 20 +MAGIC_TAB_FALADOR_TELEPORT = 21 +MAGIC_TAB_CRUMBLE_UNDEAD = 22 +MAGIC_TAB_TELEPORT_TO_HOUSE = 23 +MAGIC_TAB_WIND_BLAST = 24 +MAGIC_TAB_SUPERHEAT_ITEM = 25 +MAGIC_TAB_CAMELOT_TELEPORT = 26 +MAGIC_TAB_WATER_BLAST = 27 +MAGIC_TAB_LEVEL_THREE_ENCHANT = 28 +MAGIC_TAB_IBAN_BLAST = 29 +MAGIC_TAB_SNARE = 30 +MAGIC_TAB_MAGIC_DART = 31 +MAGIC_TAB_ARDOUGNE_TELEPORT = 32 +MAGIC_TAB_EARTH_BLAST = 33 +MAGIC_TAB_HIGH_LEVEL_ALCHEMY = 34 +MAGIC_TAB_CHARGE_WATER_ORB = 35 +MAGIC_TAB_LEVEL_FOUR_ENCHANT = 36 +MAGIC_TAB_WATCHTOWER_TELEPORT = 37 +MAGIC_TAB_FIRE_BLAST = 38 +MAGIC_TAB_CHARGE_EARTH_ORB = 39 +MAGIC_TAB_BONES_TO_PEACHES = 40 +MAGIC_TAB_SARADOMIN_STRIKE = 41 +MAGIC_TAB_CLAWS_OF_GUTHIX = 42 +MAGIC_TAB_FLAMES_OF_ZAMORAK = 43 +MAGIC_TAB_TROLLHEIM_TELEPORT = 44 +MAGIC_TAB_WIND_WAVE = 45 +MAGIC_TAB_CHARGE_FIRE_ORB = 46 +MAGIC_TAB_APE_ATOLL_TELEPORT = 47 +MAGIC_TAB_WATER_WAVE = 48 +MAGIC_TAB_CHARGE_AIR_ORB = 49 +MAGIC_TAB_VULNERABILITY = 50 +MAGIC_TAB_LEVEL_FIVE_ENCHANT = 51 +MAGIC_TAB_KOUREND_CASTLE_TELEPORT = 52 +MAGIC_TAB_EARTH_WAVE = 53 +MAGIC_TAB_ENFEEBLE = 54 +MAGIC_TAB_TELEOTHER_LUMBRIDGE = 55 +MAGIC_TAB_FIRE_WAVE = 56 +MAGIC_TAB_ENTANGLE = 57 +MAGIC_TAB_STUN = 58 +MAGIC_TAB_CHARGE = 59 +MAGIC_TAB_WIND_SURGE = 60 +MAGIC_TAB_TELEOTHER_FALADOR = 61 +MAGIC_TAB_WATER_SURGE = 62 +MAGIC_TAB_TELE_BLOCK = 63 +MAGIC_TAB_TELEPORT_TO_TARGET = 64 +MAGIC_TAB_LEVEL_SIX_ENCHANT = 65 +MAGIC_TAB_TELEOTHER_CAMELOT = 66 +MAGIC_TAB_EARTH_SURGE = 67 +MAGIC_TAB_LEVEL_SEVEN_ENCHANT = 68 +MAGIC_TAB_FIRE_SURGE = 69 + +# Prayers + +PRAYER_TAB_THICK_SKIN = 0 +PRAYER_TAB_BURST_OF_STRENGTH = 1 +PRAYER_TAB_CLARITY_OF_THOUGHT = 2 +PRAYER_TAB_SHARP_EYE = 3 +PRAYER_TAB_MYSTIC_WILL = 4 +PRAYER_TAB_ROCK_SKIN = 5 +PRAYER_TAB_SUPERHUMAN_STRENGTH = 6 +PRAYER_TAB_IMPROVED_REFLEXES = 7 +PRAYER_TAB_RAPID_RESTORE = 8 +PRAYER_TAB_RAPID_HEAL = 9 +PRAYER_TAB_PROTECT_ITEM = 10 +PRAYER_TAB_HAWK_EYE = 11 +PRAYER_TAB_MYSTIC_LORE = 12 +PRAYER_TAB_STEEL_SKIN = 13 +PRAYER_TAB_ULTIMATE_STRENGTH = 14 +PRAYER_TAB_INCREDIBLE_REFLEXES = 15 +PRAYER_TAB_PROTECT_FROM_MAGIC = 16 +PRAYER_TAB_PROTECT_FROM_MISSILES = 17 +PRAYER_TAB_PROTECT_FROM_MELEE = 18 +PRAYER_TAB_EAGLE_EYE = 19 +PRAYER_TAB_MYSTIC_MIGHT = 20 +PRAYER_TAB_RETRIBUTION = 21 +PRAYER_TAB_REDEMPTION = 22 +PRAYER_TAB_SMITE = 23 +PRAYER_TAB_PRESERVE = 24 +PRAYER_TAB_CHIVALRY = 25 +PRAYER_TAB_PIETY = 26 +PRAYER_TAB_RIGOUR = 27 +PRAYER_TAB_AUGURY = 28 + +# Skill Tabs +SKILL_TAB_ATTACK = 0 +SKILL_TAB_HITPOINTS = 1 +SKILL_TAB_MINING = 2 +SKILL_TAB_STRENGTH = 3 +SKILL_TAB_AGILITY = 4 +SKILL_TAB_SMITHING = 5 +SKILL_TAB_DEFENCE = 6 +SKILL_TAB_HERBLORE = 7 +SKILL_TAB_FISHING = 8 +SKILL_TAB_RANGING = 9 +SKILL_TAB_THIEVING = 10 +SKILL_TAB_COOKING = 11 +SKILL_TAB_PRAYER = 12 +SKILL_TAB_CRAFTING = 13 +SKILL_TAB_FIREMAKING = 14 +SKILL_TAB_MAGIC = 15 +SKILL_TAB_FLETCHING = 16 +SKILL_TAB_WOODCUTTING = 17 +SKILL_TAB_RUNECRAFT = 18 +SKILL_TAB_SLAYER = 19 +SKILL_TAB_FARMING = 20 +SKILL_TAB_CONSTRUCTION = 21 +SKILL_TAB_HUNTER = 22 +SKILL_TAB_OVERALL = 23 + +# Skill tab map +SKILL_TAB_MAP = { + "attack": SKILL_TAB_ATTACK, + "hitpoints": SKILL_TAB_HITPOINTS, + "mining": SKILL_TAB_MINING, + "strength": SKILL_TAB_STRENGTH, + "agility": SKILL_TAB_AGILITY, + "smithing": SKILL_TAB_SMITHING, + "defence": SKILL_TAB_DEFENCE, + "herblore": SKILL_TAB_HERBLORE, + "fishing": SKILL_TAB_FISHING, + "ranging": SKILL_TAB_RANGING, + "thieving": SKILL_TAB_THIEVING, + "cooking": SKILL_TAB_COOKING, + "prayer": SKILL_TAB_PRAYER, + "crafting": SKILL_TAB_CRAFTING, + "firemaking": SKILL_TAB_FIREMAKING, + "magic": SKILL_TAB_MAGIC, + "fletching": SKILL_TAB_FLETCHING, + "woodcutting": SKILL_TAB_WOODCUTTING, + "runecraft": SKILL_TAB_RUNECRAFT, + "slayer": SKILL_TAB_SLAYER, + "farming": SKILL_TAB_FARMING, + "contruction": SKILL_TAB_CONSTRUCTION, + "hunter": SKILL_TAB_HUNTER, + "overall": SKILL_TAB_OVERALL +} \ No newline at end of file diff --git a/src/utilities/window.py b/src/utilities/window.py index 6e963bbe..4abef118 100644 --- a/src/utilities/window.py +++ b/src/utilities/window.py @@ -41,6 +41,7 @@ class Window: inventory_slots: List[Rectangle] = [] # https://i.imgur.com/gBwhAwE.png spellbook_normal: List[Rectangle] = [] # https://i.imgur.com/vkKAfV5.png prayers: List[Rectangle] = [] # https://i.imgur.com/KRmC3YB.png + skill_slots: List[Rectangle] = [] # https://i.imgur.com/j83q8XC.png # Chat Area chat: Rectangle = None # https://i.imgur.com/u544ouI.png @@ -172,6 +173,7 @@ def __locate_control_panel(self, client_rect: Rectangle) -> bool: self.__locate_inv_slots(cp) self.__locate_prayers(cp) self.__locate_spells(cp) + self.__locate_skill_slots(cp) self.control_panel = cp return True print("Window.__locate_control_panel(): Failed to find control panel.") @@ -239,6 +241,21 @@ def __locate_spells(self, cp: Rectangle) -> None: self.spellbook_normal.append(Rectangle(left=x, top=y, width=slot_w, height=slot_h)) x += slot_w + gap_x y += slot_h + gap_y + + def __locate_skill_slots(self, cp: Rectangle) -> None: + """ + Creates Rectangles for each skill slot relative to the control panel, storing it in the class property. + """ + self.skill_slots = [] + slot_w, slot_h = 56, 28 # dimensions of a slot + gap_x, gap_y = 2, 2 # pixel gap between slots + y = 44 + cp.top # start y relative to cp template + for _ in range(8): + x = 40 + cp.left # start x relative to cp template + for _ in range(3): + self.skill_slots.append(Rectangle(left=x, top=y, width=slot_w, height=slot_h)) + x += slot_w + gap_x + y += slot_h + gap_y def __locate_game_view(self, client_rect: Rectangle) -> bool: """