├── logs └── .gitkeep ├── config_profiles └── .gitkeep ├── assets ├── images │ ├── targets │ │ ├── popup_erro.png │ │ ├── ship_bar_50.png │ │ ├── ship_bar_75.png │ │ ├── button_ship_x.png │ │ ├── identify_base.png │ │ ├── identify_home.png │ │ ├── identify_lose.png │ │ ├── ship_bar_100.png │ │ ├── btn_fight_boss.png │ │ ├── button_fight_off.png │ │ ├── button_fight_on.png │ │ ├── identify_hunting.png │ │ ├── identify_login.png │ │ ├── identify_victory.png │ │ ├── ship_search_area.png │ │ ├── 0_ships_in_battle.png │ │ ├── 10_ships_in_battle.png │ │ ├── 11_ships_in_battle.png │ │ ├── 12_ships_in_battle.png │ │ ├── 13_ships_in_battle.png │ │ ├── 14_ships_in_battle.png │ │ ├── 15_ships_in_battle.png │ │ ├── 1_ships_in_battle.png │ │ ├── 2_ships_in_battle.png │ │ ├── 3_ships_in_battle.png │ │ ├── 4_ships_in_battle.png │ │ ├── 5_ships_in_battle.png │ │ ├── 6_ships_in_battle.png │ │ ├── 7_ships_in_battle.png │ │ ├── 8_ships_in_battle.png │ │ ├── 9_ships_in_battle.png │ │ ├── btn_confirm_gt_10s.png │ │ ├── btn_confirm_lt_9s.png │ │ ├── button_hunt_ships.png │ │ ├── ship_bar_vertical.png │ │ ├── button_connect_wallet.png │ │ ├── button_spaceship_home.png │ │ ├── button_connect_wallet_play.png │ │ ├── button_confirm_without_time.png │ │ ├── identify_n_space_shipts_in_battle_board.png │ │ ├── identify_n_space_shipts_in_battle_end_area.png │ │ └── identify_n_space_shipts_in_battle_start_area.png │ ├── targets_global │ │ ├── screen_hd.png │ │ ├── screen_full_hd.png │ │ └── button_connect_wallet_sign.png │ └── targets_hd │ │ ├── button_ship_x.png │ │ ├── identify_base.png │ │ ├── identify_home.png │ │ ├── identify_lose.png │ │ ├── ship_bar_100.png │ │ ├── ship_bar_50.png │ │ ├── ship_bar_75.png │ │ ├── btn_fight_boss.png │ │ ├── button_fight_on.png │ │ ├── identify_login.png │ │ ├── 0_ships_in_battle.png │ │ ├── 10_ships_in_battle.png │ │ ├── 11_ships_in_battle.png │ │ ├── 12_ships_in_battle.png │ │ ├── 13_ships_in_battle.png │ │ ├── 14_ships_in_battle.png │ │ ├── 15_ships_in_battle.png │ │ ├── 1_ships_in_battle.png │ │ ├── 2_ships_in_battle.png │ │ ├── 3_ships_in_battle.png │ │ ├── 4_ships_in_battle.png │ │ ├── 5_ships_in_battle.png │ │ ├── 6_ships_in_battle.png │ │ ├── 7_ships_in_battle.png │ │ ├── 8_ships_in_battle.png │ │ ├── 9_ships_in_battle.png │ │ ├── btn_confirm_gt_10s.png │ │ ├── btn_confirm_lt_9s.png │ │ ├── button_fight_off.png │ │ ├── button_hunt_ships.png │ │ ├── identify_hunting.png │ │ ├── identify_victory.png │ │ ├── ship_search_area.png │ │ ├── identify_processing.png │ │ ├── button_connect_wallet.png │ │ ├── button_spaceship_home.png │ │ ├── button_confirm_without_time.png │ │ ├── button_connect_wallet_play.png │ │ ├── identify_n_space_shipts_in_battle_board.png │ │ ├── identify_n_space_shipts_in_battle_end_area.png │ │ └── identify_n_space_shipts_in_battle_start_area.png └── infos_and_tutorial │ ├── chat_id.png │ ├── bot_download.png │ ├── python_path.png │ ├── space_user.png │ ├── token_chat_id.png │ ├── max_ammo_sample.png │ └── bot_autoclickers_allowed.png ├── requirements.txt ├── module ├── platform.py ├── config.py ├── telegram.py ├── window.py ├── logger.py ├── utils.py ├── manager.py ├── mouse.py ├── image.py └── spaceScreen.py ├── config.yaml ├── .gitignore ├── main.py └── README.md /logs/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /config_profiles/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/images/targets/popup_erro.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renatofmmaia/spacecrypto-bot/HEAD/assets/images/targets/popup_erro.png -------------------------------------------------------------------------------- /assets/images/targets/ship_bar_50.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renatofmmaia/spacecrypto-bot/HEAD/assets/images/targets/ship_bar_50.png -------------------------------------------------------------------------------- /assets/images/targets/ship_bar_75.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renatofmmaia/spacecrypto-bot/HEAD/assets/images/targets/ship_bar_75.png -------------------------------------------------------------------------------- /assets/infos_and_tutorial/chat_id.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renatofmmaia/spacecrypto-bot/HEAD/assets/infos_and_tutorial/chat_id.png -------------------------------------------------------------------------------- /assets/images/targets/button_ship_x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renatofmmaia/spacecrypto-bot/HEAD/assets/images/targets/button_ship_x.png -------------------------------------------------------------------------------- /assets/images/targets/identify_base.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renatofmmaia/spacecrypto-bot/HEAD/assets/images/targets/identify_base.png -------------------------------------------------------------------------------- /assets/images/targets/identify_home.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renatofmmaia/spacecrypto-bot/HEAD/assets/images/targets/identify_home.png -------------------------------------------------------------------------------- /assets/images/targets/identify_lose.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renatofmmaia/spacecrypto-bot/HEAD/assets/images/targets/identify_lose.png -------------------------------------------------------------------------------- /assets/images/targets/ship_bar_100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renatofmmaia/spacecrypto-bot/HEAD/assets/images/targets/ship_bar_100.png -------------------------------------------------------------------------------- /assets/images/targets/btn_fight_boss.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renatofmmaia/spacecrypto-bot/HEAD/assets/images/targets/btn_fight_boss.png -------------------------------------------------------------------------------- /assets/images/targets/button_fight_off.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renatofmmaia/spacecrypto-bot/HEAD/assets/images/targets/button_fight_off.png -------------------------------------------------------------------------------- /assets/images/targets/button_fight_on.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renatofmmaia/spacecrypto-bot/HEAD/assets/images/targets/button_fight_on.png -------------------------------------------------------------------------------- /assets/images/targets/identify_hunting.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renatofmmaia/spacecrypto-bot/HEAD/assets/images/targets/identify_hunting.png -------------------------------------------------------------------------------- /assets/images/targets/identify_login.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renatofmmaia/spacecrypto-bot/HEAD/assets/images/targets/identify_login.png -------------------------------------------------------------------------------- /assets/images/targets/identify_victory.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renatofmmaia/spacecrypto-bot/HEAD/assets/images/targets/identify_victory.png -------------------------------------------------------------------------------- /assets/images/targets/ship_search_area.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renatofmmaia/spacecrypto-bot/HEAD/assets/images/targets/ship_search_area.png -------------------------------------------------------------------------------- /assets/images/targets_global/screen_hd.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renatofmmaia/spacecrypto-bot/HEAD/assets/images/targets_global/screen_hd.png -------------------------------------------------------------------------------- /assets/images/targets_hd/button_ship_x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renatofmmaia/spacecrypto-bot/HEAD/assets/images/targets_hd/button_ship_x.png -------------------------------------------------------------------------------- /assets/images/targets_hd/identify_base.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renatofmmaia/spacecrypto-bot/HEAD/assets/images/targets_hd/identify_base.png -------------------------------------------------------------------------------- /assets/images/targets_hd/identify_home.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renatofmmaia/spacecrypto-bot/HEAD/assets/images/targets_hd/identify_home.png -------------------------------------------------------------------------------- /assets/images/targets_hd/identify_lose.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renatofmmaia/spacecrypto-bot/HEAD/assets/images/targets_hd/identify_lose.png -------------------------------------------------------------------------------- /assets/images/targets_hd/ship_bar_100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renatofmmaia/spacecrypto-bot/HEAD/assets/images/targets_hd/ship_bar_100.png -------------------------------------------------------------------------------- /assets/images/targets_hd/ship_bar_50.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renatofmmaia/spacecrypto-bot/HEAD/assets/images/targets_hd/ship_bar_50.png -------------------------------------------------------------------------------- /assets/images/targets_hd/ship_bar_75.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renatofmmaia/spacecrypto-bot/HEAD/assets/images/targets_hd/ship_bar_75.png -------------------------------------------------------------------------------- /assets/infos_and_tutorial/bot_download.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renatofmmaia/spacecrypto-bot/HEAD/assets/infos_and_tutorial/bot_download.png -------------------------------------------------------------------------------- /assets/infos_and_tutorial/python_path.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renatofmmaia/spacecrypto-bot/HEAD/assets/infos_and_tutorial/python_path.png -------------------------------------------------------------------------------- /assets/infos_and_tutorial/space_user.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renatofmmaia/spacecrypto-bot/HEAD/assets/infos_and_tutorial/space_user.png -------------------------------------------------------------------------------- /assets/images/targets/0_ships_in_battle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renatofmmaia/spacecrypto-bot/HEAD/assets/images/targets/0_ships_in_battle.png -------------------------------------------------------------------------------- /assets/images/targets/10_ships_in_battle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renatofmmaia/spacecrypto-bot/HEAD/assets/images/targets/10_ships_in_battle.png -------------------------------------------------------------------------------- /assets/images/targets/11_ships_in_battle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renatofmmaia/spacecrypto-bot/HEAD/assets/images/targets/11_ships_in_battle.png -------------------------------------------------------------------------------- /assets/images/targets/12_ships_in_battle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renatofmmaia/spacecrypto-bot/HEAD/assets/images/targets/12_ships_in_battle.png -------------------------------------------------------------------------------- /assets/images/targets/13_ships_in_battle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renatofmmaia/spacecrypto-bot/HEAD/assets/images/targets/13_ships_in_battle.png -------------------------------------------------------------------------------- /assets/images/targets/14_ships_in_battle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renatofmmaia/spacecrypto-bot/HEAD/assets/images/targets/14_ships_in_battle.png -------------------------------------------------------------------------------- /assets/images/targets/15_ships_in_battle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renatofmmaia/spacecrypto-bot/HEAD/assets/images/targets/15_ships_in_battle.png -------------------------------------------------------------------------------- /assets/images/targets/1_ships_in_battle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renatofmmaia/spacecrypto-bot/HEAD/assets/images/targets/1_ships_in_battle.png -------------------------------------------------------------------------------- /assets/images/targets/2_ships_in_battle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renatofmmaia/spacecrypto-bot/HEAD/assets/images/targets/2_ships_in_battle.png -------------------------------------------------------------------------------- /assets/images/targets/3_ships_in_battle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renatofmmaia/spacecrypto-bot/HEAD/assets/images/targets/3_ships_in_battle.png -------------------------------------------------------------------------------- /assets/images/targets/4_ships_in_battle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renatofmmaia/spacecrypto-bot/HEAD/assets/images/targets/4_ships_in_battle.png -------------------------------------------------------------------------------- /assets/images/targets/5_ships_in_battle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renatofmmaia/spacecrypto-bot/HEAD/assets/images/targets/5_ships_in_battle.png -------------------------------------------------------------------------------- /assets/images/targets/6_ships_in_battle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renatofmmaia/spacecrypto-bot/HEAD/assets/images/targets/6_ships_in_battle.png -------------------------------------------------------------------------------- /assets/images/targets/7_ships_in_battle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renatofmmaia/spacecrypto-bot/HEAD/assets/images/targets/7_ships_in_battle.png -------------------------------------------------------------------------------- /assets/images/targets/8_ships_in_battle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renatofmmaia/spacecrypto-bot/HEAD/assets/images/targets/8_ships_in_battle.png -------------------------------------------------------------------------------- /assets/images/targets/9_ships_in_battle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renatofmmaia/spacecrypto-bot/HEAD/assets/images/targets/9_ships_in_battle.png -------------------------------------------------------------------------------- /assets/images/targets/btn_confirm_gt_10s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renatofmmaia/spacecrypto-bot/HEAD/assets/images/targets/btn_confirm_gt_10s.png -------------------------------------------------------------------------------- /assets/images/targets/btn_confirm_lt_9s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renatofmmaia/spacecrypto-bot/HEAD/assets/images/targets/btn_confirm_lt_9s.png -------------------------------------------------------------------------------- /assets/images/targets/button_hunt_ships.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renatofmmaia/spacecrypto-bot/HEAD/assets/images/targets/button_hunt_ships.png -------------------------------------------------------------------------------- /assets/images/targets/ship_bar_vertical.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renatofmmaia/spacecrypto-bot/HEAD/assets/images/targets/ship_bar_vertical.png -------------------------------------------------------------------------------- /assets/images/targets_hd/btn_fight_boss.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renatofmmaia/spacecrypto-bot/HEAD/assets/images/targets_hd/btn_fight_boss.png -------------------------------------------------------------------------------- /assets/images/targets_hd/button_fight_on.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renatofmmaia/spacecrypto-bot/HEAD/assets/images/targets_hd/button_fight_on.png -------------------------------------------------------------------------------- /assets/images/targets_hd/identify_login.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renatofmmaia/spacecrypto-bot/HEAD/assets/images/targets_hd/identify_login.png -------------------------------------------------------------------------------- /assets/infos_and_tutorial/token_chat_id.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renatofmmaia/spacecrypto-bot/HEAD/assets/infos_and_tutorial/token_chat_id.png -------------------------------------------------------------------------------- /assets/images/targets/button_connect_wallet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renatofmmaia/spacecrypto-bot/HEAD/assets/images/targets/button_connect_wallet.png -------------------------------------------------------------------------------- /assets/images/targets/button_spaceship_home.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renatofmmaia/spacecrypto-bot/HEAD/assets/images/targets/button_spaceship_home.png -------------------------------------------------------------------------------- /assets/images/targets_global/screen_full_hd.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renatofmmaia/spacecrypto-bot/HEAD/assets/images/targets_global/screen_full_hd.png -------------------------------------------------------------------------------- /assets/images/targets_hd/0_ships_in_battle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renatofmmaia/spacecrypto-bot/HEAD/assets/images/targets_hd/0_ships_in_battle.png -------------------------------------------------------------------------------- /assets/images/targets_hd/10_ships_in_battle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renatofmmaia/spacecrypto-bot/HEAD/assets/images/targets_hd/10_ships_in_battle.png -------------------------------------------------------------------------------- /assets/images/targets_hd/11_ships_in_battle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renatofmmaia/spacecrypto-bot/HEAD/assets/images/targets_hd/11_ships_in_battle.png -------------------------------------------------------------------------------- /assets/images/targets_hd/12_ships_in_battle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renatofmmaia/spacecrypto-bot/HEAD/assets/images/targets_hd/12_ships_in_battle.png -------------------------------------------------------------------------------- /assets/images/targets_hd/13_ships_in_battle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renatofmmaia/spacecrypto-bot/HEAD/assets/images/targets_hd/13_ships_in_battle.png -------------------------------------------------------------------------------- /assets/images/targets_hd/14_ships_in_battle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renatofmmaia/spacecrypto-bot/HEAD/assets/images/targets_hd/14_ships_in_battle.png -------------------------------------------------------------------------------- /assets/images/targets_hd/15_ships_in_battle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renatofmmaia/spacecrypto-bot/HEAD/assets/images/targets_hd/15_ships_in_battle.png -------------------------------------------------------------------------------- /assets/images/targets_hd/1_ships_in_battle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renatofmmaia/spacecrypto-bot/HEAD/assets/images/targets_hd/1_ships_in_battle.png -------------------------------------------------------------------------------- /assets/images/targets_hd/2_ships_in_battle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renatofmmaia/spacecrypto-bot/HEAD/assets/images/targets_hd/2_ships_in_battle.png -------------------------------------------------------------------------------- /assets/images/targets_hd/3_ships_in_battle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renatofmmaia/spacecrypto-bot/HEAD/assets/images/targets_hd/3_ships_in_battle.png -------------------------------------------------------------------------------- /assets/images/targets_hd/4_ships_in_battle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renatofmmaia/spacecrypto-bot/HEAD/assets/images/targets_hd/4_ships_in_battle.png -------------------------------------------------------------------------------- /assets/images/targets_hd/5_ships_in_battle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renatofmmaia/spacecrypto-bot/HEAD/assets/images/targets_hd/5_ships_in_battle.png -------------------------------------------------------------------------------- /assets/images/targets_hd/6_ships_in_battle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renatofmmaia/spacecrypto-bot/HEAD/assets/images/targets_hd/6_ships_in_battle.png -------------------------------------------------------------------------------- /assets/images/targets_hd/7_ships_in_battle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renatofmmaia/spacecrypto-bot/HEAD/assets/images/targets_hd/7_ships_in_battle.png -------------------------------------------------------------------------------- /assets/images/targets_hd/8_ships_in_battle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renatofmmaia/spacecrypto-bot/HEAD/assets/images/targets_hd/8_ships_in_battle.png -------------------------------------------------------------------------------- /assets/images/targets_hd/9_ships_in_battle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renatofmmaia/spacecrypto-bot/HEAD/assets/images/targets_hd/9_ships_in_battle.png -------------------------------------------------------------------------------- /assets/images/targets_hd/btn_confirm_gt_10s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renatofmmaia/spacecrypto-bot/HEAD/assets/images/targets_hd/btn_confirm_gt_10s.png -------------------------------------------------------------------------------- /assets/images/targets_hd/btn_confirm_lt_9s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renatofmmaia/spacecrypto-bot/HEAD/assets/images/targets_hd/btn_confirm_lt_9s.png -------------------------------------------------------------------------------- /assets/images/targets_hd/button_fight_off.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renatofmmaia/spacecrypto-bot/HEAD/assets/images/targets_hd/button_fight_off.png -------------------------------------------------------------------------------- /assets/images/targets_hd/button_hunt_ships.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renatofmmaia/spacecrypto-bot/HEAD/assets/images/targets_hd/button_hunt_ships.png -------------------------------------------------------------------------------- /assets/images/targets_hd/identify_hunting.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renatofmmaia/spacecrypto-bot/HEAD/assets/images/targets_hd/identify_hunting.png -------------------------------------------------------------------------------- /assets/images/targets_hd/identify_victory.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renatofmmaia/spacecrypto-bot/HEAD/assets/images/targets_hd/identify_victory.png -------------------------------------------------------------------------------- /assets/images/targets_hd/ship_search_area.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renatofmmaia/spacecrypto-bot/HEAD/assets/images/targets_hd/ship_search_area.png -------------------------------------------------------------------------------- /assets/infos_and_tutorial/max_ammo_sample.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renatofmmaia/spacecrypto-bot/HEAD/assets/infos_and_tutorial/max_ammo_sample.png -------------------------------------------------------------------------------- /assets/images/targets_hd/identify_processing.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renatofmmaia/spacecrypto-bot/HEAD/assets/images/targets_hd/identify_processing.png -------------------------------------------------------------------------------- /assets/images/targets/button_connect_wallet_play.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renatofmmaia/spacecrypto-bot/HEAD/assets/images/targets/button_connect_wallet_play.png -------------------------------------------------------------------------------- /assets/images/targets_hd/button_connect_wallet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renatofmmaia/spacecrypto-bot/HEAD/assets/images/targets_hd/button_connect_wallet.png -------------------------------------------------------------------------------- /assets/images/targets_hd/button_spaceship_home.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renatofmmaia/spacecrypto-bot/HEAD/assets/images/targets_hd/button_spaceship_home.png -------------------------------------------------------------------------------- /assets/images/targets/button_confirm_without_time.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renatofmmaia/spacecrypto-bot/HEAD/assets/images/targets/button_confirm_without_time.png -------------------------------------------------------------------------------- /assets/infos_and_tutorial/bot_autoclickers_allowed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renatofmmaia/spacecrypto-bot/HEAD/assets/infos_and_tutorial/bot_autoclickers_allowed.png -------------------------------------------------------------------------------- /assets/images/targets_hd/button_confirm_without_time.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renatofmmaia/spacecrypto-bot/HEAD/assets/images/targets_hd/button_confirm_without_time.png -------------------------------------------------------------------------------- /assets/images/targets_hd/button_connect_wallet_play.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renatofmmaia/spacecrypto-bot/HEAD/assets/images/targets_hd/button_connect_wallet_play.png -------------------------------------------------------------------------------- /assets/images/targets_global/button_connect_wallet_sign.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renatofmmaia/spacecrypto-bot/HEAD/assets/images/targets_global/button_connect_wallet_sign.png -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | mss==6.1.0 2 | opencv-python==4.5.4.60 3 | packaging==21.3 4 | pillow==9.0.0 5 | pyautogui==0.9.53 6 | python-telegram-bot==13.10 7 | pyyaml==6.0 8 | requests==2.27.1 -------------------------------------------------------------------------------- /assets/images/targets/identify_n_space_shipts_in_battle_board.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renatofmmaia/spacecrypto-bot/HEAD/assets/images/targets/identify_n_space_shipts_in_battle_board.png -------------------------------------------------------------------------------- /assets/images/targets/identify_n_space_shipts_in_battle_end_area.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renatofmmaia/spacecrypto-bot/HEAD/assets/images/targets/identify_n_space_shipts_in_battle_end_area.png -------------------------------------------------------------------------------- /assets/images/targets_hd/identify_n_space_shipts_in_battle_board.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renatofmmaia/spacecrypto-bot/HEAD/assets/images/targets_hd/identify_n_space_shipts_in_battle_board.png -------------------------------------------------------------------------------- /assets/images/targets/identify_n_space_shipts_in_battle_start_area.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renatofmmaia/spacecrypto-bot/HEAD/assets/images/targets/identify_n_space_shipts_in_battle_start_area.png -------------------------------------------------------------------------------- /assets/images/targets_hd/identify_n_space_shipts_in_battle_end_area.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renatofmmaia/spacecrypto-bot/HEAD/assets/images/targets_hd/identify_n_space_shipts_in_battle_end_area.png -------------------------------------------------------------------------------- /assets/images/targets_hd/identify_n_space_shipts_in_battle_start_area.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/renatofmmaia/spacecrypto-bot/HEAD/assets/images/targets_hd/identify_n_space_shipts_in_battle_start_area.png -------------------------------------------------------------------------------- /module/platform.py: -------------------------------------------------------------------------------- 1 | import sys 2 | from enum import Enum 3 | 4 | 5 | class PlatformEnum(Enum): 6 | LINUX = 1 7 | WINDOWS = 2 8 | 9 | 10 | class Platform: 11 | def get_platform(self): 12 | is_linux = sys.platform == "linux" or sys.platform == "linux2" 13 | if is_linux: 14 | return PlatformEnum.LINUX 15 | else: 16 | return PlatformEnum.WINDOWS 17 | -------------------------------------------------------------------------------- /module/config.py: -------------------------------------------------------------------------------- 1 | import yaml 2 | 3 | 4 | class Config: 5 | PROPERTIES = {} 6 | 7 | @staticmethod 8 | def load_config(config_file): 9 | with open(config_file, "r") as stream: 10 | Config.PROPERTIES = yaml.safe_load(stream) 11 | 12 | def get(*args): 13 | value_to_return = Config.PROPERTIES 14 | for arg in args: 15 | value_to_return = value_to_return[arg] 16 | return value_to_return 17 | 18 | -------------------------------------------------------------------------------- /module/telegram.py: -------------------------------------------------------------------------------- 1 | from .config import Config 2 | import telegram 3 | 4 | class TelegramBot: 5 | TOKEN = None 6 | CHAT_ID = None 7 | BOT = None 8 | ACTIVE = False 9 | 10 | def load_config(): 11 | TelegramBot.TOKEN = Config.get('telegram','token') 12 | TelegramBot.CHAT_ID = Config.get('telegram','chat_id') 13 | 14 | if (TelegramBot.TOKEN and (TelegramBot.CHAT_ID and TelegramBot.CHAT_ID != 0)): 15 | TelegramBot.ACTIVE = True 16 | 17 | if TelegramBot.ACTIVE: 18 | TelegramBot.BOT = telegram.Bot(token=TelegramBot.TOKEN) 19 | 20 | def send_message_with_image(image_path: str, message: str = None): 21 | if TelegramBot.ACTIVE: 22 | if message: 23 | TelegramBot.send_message(message) 24 | 25 | TelegramBot.BOT.send_photo(chat_id=TelegramBot.CHAT_ID, photo=open(image_path, 'rb')) 26 | 27 | def send_message(message: str): 28 | if TelegramBot.ACTIVE: 29 | TelegramBot.BOT.send_message(chat_id=TelegramBot.CHAT_ID, text=message) 30 | -------------------------------------------------------------------------------- /module/window.py: -------------------------------------------------------------------------------- 1 | import subprocess 2 | from tkinter import * 3 | from tkinter.ttk import * 4 | from enum import Enum 5 | 6 | from module.platform import Platform, PlatformEnum 7 | 8 | 9 | def get_windows(title:str): 10 | return ( 11 | _get_linux_bombcrypto_windows(title) 12 | if Platform().get_platform() == PlatformEnum.LINUX 13 | else _get_bombcrypto_windows(title) 14 | ) 15 | 16 | 17 | def _get_linux_bombcrypto_windows(title): 18 | stdout = ( 19 | subprocess.Popen( 20 | f"xdotool search --name '{title}'", shell=True, stdout=subprocess.PIPE 21 | ) 22 | .communicate()[0] 23 | .decode("utf-8") 24 | .strip() 25 | ) 26 | windows = stdout.split("\n") 27 | return [LinuxWindow(w) for w in windows] 28 | 29 | def _get_bombcrypto_windows(title): 30 | import pygetwindow 31 | 32 | return [DefaultWindow(w) for w in pygetwindow.getWindowsWithTitle(title)] 33 | 34 | def get_resolution(): 35 | root = Tk() 36 | width = root.winfo_screenwidth() 37 | height = root.winfo_screenheight() 38 | 39 | if width == 1920 and height == 1080: 40 | return WindowsResolutionEnum.FULL_HD 41 | else: 42 | return WindowsResolutionEnum.NOT_SUPPORTED 43 | 44 | class LinuxWindow: 45 | def __init__(self, window_id) -> None: 46 | self.window = window_id 47 | 48 | def activate(self): 49 | subprocess.Popen(f"xdotool windowactivate {self.window}", shell=True) 50 | 51 | class DefaultWindow: 52 | def __init__(self, window) -> None: 53 | self.window = window 54 | 55 | def activate(self): 56 | self.window.activate() 57 | 58 | class WindowsResolutionEnum(Enum): 59 | FULL_HD = "1920x1080" 60 | NOT_SUPPORTED = "NOT_SUPPORTED" 61 | -------------------------------------------------------------------------------- /module/logger.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import time 3 | from .config import Config 4 | from enum import Enum 5 | 6 | class LoggerEnum(Enum): 7 | ACTION = 0 8 | BUTTON_CLICK = 1 9 | PAGE_FOUND = 2 10 | TIMER_REFRESH = 3 11 | ERROR = 4 12 | 13 | 14 | COLOR = { 15 | "blue": "\033[94m", 16 | "default": "\033[99m", 17 | "grey": "\033[90m", 18 | "yellow": "\033[93m", 19 | "black": "\033[90m", 20 | "cyan": "\033[96m", 21 | "green": "\033[92m", 22 | "magenta": "\033[95m", 23 | "white": "\033[97m", 24 | "red": "\033[91m", 25 | } 26 | 27 | 28 | def logger(message, color="default", force_log_file=False, terminal=True, datetime=True, end='\n'): 29 | color_formatted = COLOR.get(color.lower(), COLOR["default"]) 30 | formatted_datetime = time.strftime("%m-%d %H:%M", time.localtime()) 31 | 32 | if datetime: 33 | formatted_message = "[{}] => {}".format(formatted_datetime, message) 34 | else: 35 | formatted_message = message 36 | 37 | formatted_message_colored = color_formatted + formatted_message + "\033[0m" 38 | 39 | if terminal: 40 | sys.stdout.write(color_formatted) 41 | sys.stdout.flush() 42 | print(formatted_message_colored, end=end) 43 | 44 | if Config.get('generals','save_log_file') or force_log_file: 45 | with open("./logs/logger.log", "a+", encoding='utf-8') as logger_file: 46 | logger_file.write(formatted_message + '\n') 47 | 48 | def logger_translated(text: str, loggerEnum: LoggerEnum): 49 | if loggerEnum.value == LoggerEnum.ACTION.value: 50 | logger(f"🐧 Performing {text} action") 51 | elif loggerEnum.value == LoggerEnum.BUTTON_CLICK.value: 52 | logger(f"❎ Clicking in {text} button...") 53 | elif loggerEnum.value == LoggerEnum.PAGE_FOUND.value: 54 | logger(f"🚩 {text} page detected.") 55 | elif loggerEnum.value == LoggerEnum.TIMER_REFRESH.value: 56 | logger(f"🍺 Refresh {text}.") 57 | elif loggerEnum.value == LoggerEnum.ERROR.value: 58 | logger(f"🆘 {text}.") 59 | 60 | def reset_log_file(): 61 | file = open("./logs/logger.log","w") 62 | file.close() 63 | -------------------------------------------------------------------------------- /config.yaml: -------------------------------------------------------------------------------- 1 | # Time the bot must relocate the ships to farm 2 | refresh_ships: 25 3 | 4 | # Number of ships you want to farm 5 | n_ships_to_fight: 15 6 | 7 | # Minimum number to start a battle 8 | n_minimum_ships_to_fight: 10 9 | 10 | # Percentage at which ships return 11 | # Accepted values: 50, 75 e 100 12 | ship_work_percent: 50 13 | 14 | # --------------------------------------------------------- 15 | telegram: 16 | # Settings for telegram integration 17 | token: "" 18 | chat_id: 0 19 | 20 | # Timer when your chest image is sent to telegram 21 | refresh_print_token: 60 22 | # --------------------------------------------------------- 23 | 24 | # --------------------------------------------------------- 25 | screen: 26 | scroll: 27 | # Total number of times the screen scrolls down 28 | # Every 10 ships, use 3 scrolls. 29 | # Example: 30 | # if u have 10 spaceships: 4 // if u have 20 spaceships: 8 // if u have 30 spaceships: 12 // ETC 31 | repeat: 8 32 | 33 | # Distance when scrolling down 34 | distance: -175 35 | 36 | # Duration of scrolling 37 | duration: 2 38 | 39 | # Wait time to stop scrolling before checking the heroes on the screen. 40 | wait: 1 41 | 42 | # Number of login attempts 43 | number_login_attempts: 3 44 | 45 | # Timer to check popup screen errors, if it's in error, restarts with login again 46 | refresh_check_error: 5 47 | # --------------------------------------------------------- 48 | 49 | # --------------------------------------------------------- 50 | generals: 51 | # Save all logs in file logs/logger.txt 52 | # 0: Don't save log 53 | # 1: Save log 54 | save_log_file: 0 55 | 56 | # Reset log file on start 57 | # 0: false 58 | # 1: true 59 | reset_log_file: 1 60 | 61 | # Which hotkey is used to refresh the browser 62 | # 1: CTRL + F5 63 | # 2: CTRL + SHIFT + R 64 | refresh_page_shortcut: 1 65 | # --------------------------------------------------------- 66 | 67 | 68 | # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 69 | # DONT CHANGE THIS CONFIGS 70 | # ------------------------ 71 | threshold: 72 | default: 0.7 73 | to_work: 0.8 74 | # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 75 | -------------------------------------------------------------------------------- /module/utils.py: -------------------------------------------------------------------------------- 1 | import time 2 | from random import * 3 | 4 | import pyautogui 5 | 6 | from .config import Config 7 | from .logger import logger 8 | 9 | 10 | def date_formatted(format="%Y-%m-%d %H:%M:%S"): 11 | return time.strftime(format, time.localtime()) 12 | 13 | 14 | def replace(string, strReplace): 15 | if strReplace and string.endswith(strReplace): 16 | return string[: -len(strReplace)] 17 | return string 18 | 19 | 20 | def randomness_number(n, randomn_factor_size=None): 21 | if randomn_factor_size is None: 22 | randomness_percentage = 0.1 23 | randomn_factor_size = randomness_percentage * n 24 | 25 | random_factor = 2 * random() * randomn_factor_size 26 | if random_factor > 5: 27 | random_factor = 5 28 | without_average_random_factor = n - randomn_factor_size 29 | randomized_n = int(without_average_random_factor + random_factor) 30 | 31 | return int(randomized_n) 32 | 33 | def randomize(loc: float, width: float, safe_factor=0): 34 | """randomize a number between loc and width with a safe distance (safe_factor*width). 35 | 36 | Returns 37 | ------- 38 | float 39 | random float 40 | """ 41 | if safe_factor > 0.5: 42 | raise ValueError("safe_factor must be between 0 and 0.5") 43 | 44 | safe_dist = width * safe_factor 45 | min_value = loc + safe_dist 46 | max_value = loc + width - safe_dist 47 | 48 | return uniform(min_value, max_value) 49 | 50 | def randomize_int(loc: float, width: float, safe_factor=0): 51 | """randomize a number between loc and width with a safe distance (safe_factor*width). 52 | 53 | Returns 54 | ------- 55 | int 56 | random integer 57 | """ 58 | return round(randomize(loc, width, safe_factor)) 59 | 60 | def refresh_page(delay:int = 5): 61 | logger("🌍 Refreshing browser!") 62 | 63 | shortcut_config = Config.get('generals','refresh_page_shortcut') 64 | if shortcut_config == 1: 65 | pyautogui.hotkey('ctrl', 'f5') 66 | else: 67 | with pyautogui.hold('ctrl'): 68 | with pyautogui.hold('shift'): 69 | pyautogui.press('r') 70 | 71 | def do_with_timeout(function, args = [], kwargs = {}, time_beteween: float = 0.5, timeout: float = 20): 72 | start_time = time.time() 73 | while True: 74 | if time.time() - start_time > timeout: 75 | return None 76 | 77 | result = function(*args, **kwargs) 78 | 79 | if result is not None: 80 | return result 81 | 82 | time.sleep(time_beteween) 83 | 84 | def now(): 85 | return time.time() -------------------------------------------------------------------------------- /module/manager.py: -------------------------------------------------------------------------------- 1 | import time 2 | 3 | from .spaceScreen import SpaceScreen, SpaceScreenEnum, Login, Ship 4 | from .logger import logger 5 | from .mouse import * 6 | from .utils import * 7 | from .window import get_windows 8 | from .config import Config 9 | from enum import Enum 10 | 11 | def create_managers(): 12 | return [Manager(w) for w in get_windows("Space Crypto")] 13 | 14 | class StateEnum(Enum): 15 | STARTING = 0, 16 | FIGHTING = 1, 17 | RECHARGE = 2, 18 | 19 | class Manager: 20 | def __init__(self, window) -> None: 21 | self.window = window 22 | self.refresh_check_error = 0 23 | self.refresh_ships = 0 24 | self.refresh_print_token = 0 25 | self.state = StateEnum.STARTING 26 | 27 | 28 | def __enter__(self): 29 | self.window.activate() 30 | time.sleep(2) 31 | return self 32 | 33 | def __exit__(self, type, value, tb): 34 | return 35 | 36 | def do_what_needs_to_be_done(self, current_screen): 37 | 38 | check_error = current_screen == SpaceScreenEnum.POPUP_ERROR.value or current_screen == SpaceScreenEnum.NOT_FOUND.value 39 | 40 | refresh_check_error = Config.get('screen', 'refresh_check_error')*60 41 | if ((check_error) or (refresh_check_error and (now() - self.refresh_check_error > refresh_check_error))): 42 | Ship.do_check_error(self) 43 | 44 | Ship.check_lose(self) 45 | Ship.check_victory(self) 46 | 47 | refresh_ships = Config.get('refresh_ships')*60 48 | if (refresh_ships and (now() - self.refresh_ships > refresh_ships)): 49 | Ship.keep_working(self) 50 | 51 | if Config.get('telegram','token') and Config.get('telegram','chat_id'): 52 | refresh_print_token = Config.get('telegram', 'refresh_print_token')*60 53 | if (refresh_print_token and (now() - self.refresh_print_token > refresh_print_token)): 54 | SpaceScreen.do_print_token(self) 55 | 56 | return True 57 | 58 | def set_refresh_timer(self, propertie_name): 59 | setattr(self, propertie_name, time.time()) 60 | 61 | @property 62 | def is_starting(self): 63 | return self.state == StateEnum.STARTING 64 | 65 | def set_fighting(self): 66 | logger("💪 change state to fighting") 67 | self.state = StateEnum.FIGHTING 68 | 69 | @property 70 | def is_fighting(self): 71 | return self.state == StateEnum.FIGHTING 72 | 73 | def set_recharge(self): 74 | logger("💤 change state to recharge") 75 | self.state = StateEnum.RECHARGE 76 | 77 | @property 78 | def is_recharging(self): 79 | return self.state == StateEnum.RECHARGE 80 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ### Custom ### 2 | 3 | test.py 4 | logs/* 5 | config_profiles/* 6 | print.png 7 | assets/images/targets_user* 8 | assets/images/targets_global/screen_user.png 9 | !*/.gitkeep 10 | ### Python ### 11 | # Byte-compiled / optimized / DLL files 12 | __pycache__/ 13 | *.py[cod] 14 | *$py.class 15 | 16 | # C extensions 17 | *.so 18 | 19 | # Distribution / packaging 20 | .Python 21 | build/ 22 | develop-eggs/ 23 | dist/ 24 | downloads/ 25 | eggs/ 26 | .eggs/ 27 | lib/ 28 | lib64/ 29 | parts/ 30 | sdist/ 31 | var/ 32 | wheels/ 33 | share/python-wheels/ 34 | *.egg-info/ 35 | .installed.cfg 36 | *.egg 37 | MANIFEST 38 | 39 | # PyInstaller 40 | # Usually these files are written by a python script from a template 41 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 42 | *.manifest 43 | *.spec 44 | 45 | # Installer logs 46 | pip-log.txt 47 | pip-delete-this-directory.txt 48 | 49 | # Unit test / coverage reports 50 | htmlcov/ 51 | .tox/ 52 | .nox/ 53 | .coverage 54 | .coverage.* 55 | .cache 56 | nosetests.xml 57 | coverage.xml 58 | *.cover 59 | *.py,cover 60 | .hypothesis/ 61 | .pytest_cache/ 62 | cover/ 63 | 64 | # Translations 65 | *.mo 66 | *.pot 67 | 68 | # Django stuff: 69 | *.log 70 | local_settings.py 71 | db.sqlite3 72 | db.sqlite3-journal 73 | 74 | # Flask stuff: 75 | instance/ 76 | .webassets-cache 77 | 78 | # Scrapy stuff: 79 | .scrapy 80 | 81 | # Sphinx documentation 82 | docs/_build/ 83 | 84 | # PyBuilder 85 | .pybuilder/ 86 | target/ 87 | 88 | # Jupyter Notebook 89 | .ipynb_checkpoints 90 | 91 | # IPython 92 | profile_default/ 93 | ipython_config.py 94 | 95 | # pyenv 96 | # For a library or package, you might want to ignore these files since the code is 97 | # intended to run in multiple environments; otherwise, check them in: 98 | # .python-version 99 | 100 | # pipenv 101 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 102 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 103 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 104 | # install all needed dependencies. 105 | #Pipfile.lock 106 | 107 | # poetry 108 | # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. 109 | # This is especially recommended for binary packages to ensure reproducibility, and is more 110 | # commonly ignored for libraries. 111 | # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control 112 | #poetry.lock 113 | 114 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow 115 | __pypackages__/ 116 | 117 | # Celery stuff 118 | celerybeat-schedule 119 | celerybeat.pid 120 | 121 | # SageMath parsed files 122 | *.sage.py 123 | 124 | # Environments 125 | .env 126 | .venv 127 | env/ 128 | venv/ 129 | ENV/ 130 | env.bak/ 131 | venv.bak/ 132 | 133 | # Spyder project settings 134 | .spyderproject 135 | .spyproject 136 | 137 | # Rope project settings 138 | .ropeproject 139 | 140 | # mkdocs documentation 141 | /site 142 | 143 | # mypy 144 | .mypy_cache/ 145 | .dmypy.json 146 | dmypy.json 147 | 148 | # Pyre type checker 149 | .pyre/ 150 | 151 | # pytype static type analyzer 152 | .pytype/ 153 | 154 | # Cython debug symbols 155 | cython_debug/ 156 | 157 | # vscode plugins 158 | /.history 159 | .vscode/launch.json 160 | 161 | # PyCharm 162 | # JetBrains specific template is maintainted in a separate JetBrains.gitignore that can 163 | # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore 164 | # and can be added to the global gitignore or merged into this file. For a more nuclear 165 | # option (not recommended) you can uncomment the following to ignore the entire idea folder. 166 | #.idea/ 167 | -------------------------------------------------------------------------------- /main.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import traceback 3 | from time import sleep 4 | import numpy as np 5 | import PIL 6 | 7 | import requests 8 | from packaging import version 9 | 10 | from module.spaceScreen import SpaceScreen, SpaceScreenEnum 11 | from module.config import Config 12 | from module.image import Image 13 | from module.logger import logger, reset_log_file 14 | from module.manager import create_managers 15 | from module.telegram import TelegramBot 16 | from module.window import get_resolution, WindowsResolutionEnum 17 | 18 | __version__ = "0.0.8" 19 | 20 | 21 | def main(config_file): 22 | try: 23 | # Load configs 24 | Config.load_config(config_file) 25 | TelegramBot.load_config() 26 | Image.load_targets_global() 27 | Image.load_targets_default() 28 | Image.load_targets_user() 29 | 30 | if Config.get("generals", "reset_log_file"): 31 | reset_log_file() 32 | 33 | r = requests.get( 34 | "https://api.github.com/gists/024d69fc0ea70ebf5bde3d26d91776e1" 35 | ) 36 | if r.ok: 37 | data = r.json() 38 | 39 | start_message = data["files"]["start_message"]["content"] 40 | logger(start_message, color="cyan", datetime=False) 41 | 42 | last_version = data["files"]["version"]["content"].strip() 43 | version_installed = version.parse(__version__) 44 | logger(f"-> Current version: {version_installed}", color="cyan", datetime=False) 45 | 46 | if version.parse(last_version) > version.parse(__version__): 47 | logger("-----------------------------------------------", color="green", datetime=False) 48 | logger(f"New version available: {last_version}.", color="green", datetime=False) 49 | update_message = data["files"]["update_message"]["content"] 50 | logger(update_message, color="green", datetime=False) 51 | logger("-----------------------------------------------", color="green", datetime=False) 52 | else: 53 | logger("Unable to check for updates.") 54 | 55 | managers = create_managers() 56 | logger(f"{len(managers)} Spacecrypto window (s) found") 57 | browser_count = 1 58 | show_initial_screen_message = True 59 | while True: 60 | try: 61 | for manager in managers: 62 | current_screen = SpaceScreen.get_current_screen() 63 | 64 | if show_initial_screen_message: 65 | logger(f"💫 Spacecrypto window[{browser_count}] inicializado em: {SpaceScreenEnum(current_screen).name}") 66 | 67 | with manager: 68 | manager.do_what_needs_to_be_done(current_screen) 69 | 70 | if browser_count == len(managers): 71 | browser_count = 1 72 | show_initial_screen_message = False 73 | else: 74 | browser_count += 1 75 | except Exception as e: 76 | logger( 77 | traceback.format_exc(), 78 | color="red", 79 | force_log_file=True, 80 | terminal=False, 81 | ) 82 | logger( 83 | f"😬 Ohh no! A error has occurred in the last action.\n{e}\n Check the log file for more details.", 84 | color="yellow", 85 | ) 86 | sleep(5) 87 | except Exception as e: 88 | logger(traceback.format_exc(), color="red", force_log_file=True, terminal=False) 89 | logger("😬 Ohh no! We couldn't start the bot.", color="red") 90 | 91 | 92 | if __name__ == "__main__": 93 | config_path = "config.yaml" 94 | 95 | if len(sys.argv) > 1: 96 | config_file = sys.argv[1] 97 | config_path = f"config_profiles/{config_file}.yaml" 98 | 99 | main(config_path) 100 | -------------------------------------------------------------------------------- /module/mouse.py: -------------------------------------------------------------------------------- 1 | import time 2 | 3 | import PIL.Image 4 | import pyautogui 5 | 6 | from .image import Image 7 | from .logger import logger 8 | from .utils import * 9 | 10 | 11 | def click_on_multiple_targets(target: str, not_click:str= None, filter_func = None): 12 | """click in a list of target. Returns number of clicks""" 13 | targets_positions = Image.get_target_positions(target, not_target=not_click) 14 | n_before = (len(targets_positions)) 15 | logger(f"found {n_before} targets") 16 | if filter_func is not None: 17 | targets_positions = filter(filter_func, targets_positions) 18 | logger(f"{n_before - len(list(targets_positions))} targets filtered") 19 | click_count = 0 20 | for x, y, w, h in targets_positions: 21 | x, y, move_duration, click_duration, time_between = randomize_values(x, w, y, h) 22 | pyautogui.moveTo(x, y, duration=move_duration, tween=pyautogui.easeOutQuad) 23 | time.sleep(time_between) 24 | pyautogui.click(duration=click_duration) 25 | click_count += 1 26 | 27 | return click_count 28 | 29 | def click_one_target(target: str, target_global: bool = False): 30 | """click in a target. Returns number of clicks""" 31 | result = None 32 | try: 33 | x_left, y_top, w, h = Image.get_one_target_position(target, target_global=target_global) 34 | x, y, move_duration, click_duration, time_between = randomize_values(x_left, w, y_top, h) 35 | pyautogui.moveTo(x, y, duration=move_duration, tween=pyautogui.easeOutQuad) 36 | time.sleep(time_between) 37 | pyautogui.click(duration=click_duration) 38 | result = True 39 | except Exception as e: 40 | return None 41 | # logger(f"Error: {e}") 42 | 43 | return result 44 | 45 | def click_in_one_of_targets(targets: list, target_global: bool = False): 46 | for target in targets: 47 | if click_one_target(target): 48 | return True 49 | 50 | def click_randomly_in_position(x, y, w, h): 51 | x, y, move_duration, click_duration, time_between = randomize_values(x, w, y, h) 52 | pyautogui.moveTo(x, y, duration=move_duration, tween=pyautogui.easeOutQuad) 53 | time.sleep(time_between) 54 | pyautogui.click(duration=click_duration) 55 | 56 | 57 | def click_when_target_appears(target: str, time_beteween: float = 0.5, timeout: float = 10, target_global = False): 58 | """ Click in a target when it appears. 59 | It will check for target every `time_beteween` seconds. 60 | After timeout seconds it will return 0 if no target was found. 61 | Returns 1 if target was found. 62 | """ 63 | return do_with_timeout(click_one_target, args = [target, target_global]) 64 | 65 | def click_when_one_of_targets_appears(targets: list, time_beteween: float = 0.5, timeout: float = 10, target_global = False): 66 | return do_with_timeout(click_in_one_of_targets, args = [targets, target_global]) 67 | 68 | def randomize_values(x, w, y, h): 69 | x_rand = randomize_int(x, w, 0.20) 70 | y_rand = randomize_int(y, h, 0.20) 71 | move_duration = randomize(0.1, 0.5) 72 | click_duration = randomize(0.05, 0.2) 73 | time_between = randomize(0.05, 0.3) 74 | 75 | return x_rand, y_rand, move_duration, click_duration, time_between 76 | 77 | def move_to(target:str): 78 | def move_to_logical(): 79 | try: 80 | x, y, w, h = Image.get_one_target_position(target) 81 | x, y, move_duration, click_duration, time_between = randomize_values(x, w, y, h) 82 | pyautogui.moveTo(x, y, duration=move_duration, tween=pyautogui.easeOutQuad) 83 | return True 84 | except Exception as e: 85 | return None 86 | 87 | return do_with_timeout(move_to_logical) 88 | 89 | def move_to_one_of_targets(targets: list, target_global: bool = False): 90 | for target in targets: 91 | if move_to(target): 92 | return True 93 | 94 | def move_to_when_one_of_targets_appears(targets: list, time_beteween: float = 0.5, timeout: float = 10, target_global = False): 95 | return do_with_timeout(move_to_one_of_targets, args = [targets, target_global], time_beteween=time_beteween, timeout=timeout) 96 | 97 | def scroll_and_click_on_targets(safe_scroll_target: str, repeat: int, distance:float, duration: float, wait:float, function_between, execute_before=True): 98 | res = [] 99 | if execute_before: 100 | res.append(function_between()) 101 | 102 | for i in range(repeat): 103 | move_to(safe_scroll_target) 104 | pyautogui.mouseDown(duration=0.1) 105 | pyautogui.moveRel(0, distance, duration) 106 | time.sleep(0.3) 107 | pyautogui.mouseUp(duration=0.1) 108 | time.sleep(wait) 109 | click_when_target_appears(safe_scroll_target) 110 | res.append(function_between()) 111 | 112 | return res 113 | 114 | def scroll(safe_scroll_target, distance:float, duration: float, wait:float): 115 | 116 | if type(safe_scroll_target) is list: 117 | move_to_when_one_of_targets_appears(safe_scroll_target) 118 | else: 119 | move_to(safe_scroll_target) 120 | 121 | pyautogui.mouseDown(duration=0.1) 122 | pyautogui.moveRel(0, distance, duration) 123 | time.sleep(0.3) 124 | pyautogui.mouseUp(duration=0.1) 125 | time.sleep(wait) -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Spacecrypto Bot [Family JOW] 2 | Bot desenvolvido em python, 100% do código é aberto, para aqueles que tenham conhecimento validarem que não existe nenhum código malicioso, o bot apenas trabalha com reconhecimento de imagens para poder gerenciar as interações na tela, compatível com Windows e Linux. 3 | O bot em constante atualização, e para que ele continue 100% free, não deixei de realizar sua contribuição, isso nos motiva a continuar! 4 | 5 | # Doações 6 | Faça seus testes, esta usando e ele te ajuda a otimizar seus ganhos? Mostre seu agradecimento em BUSD/BNB/SPG/SPE, assim nossa equipe se mantem empenhada em atualizar e trazer novas funcionalidades para a comunidade :relaxed: 7 | 8 | Smart Chain Wallet(BUSD/BNB/SPG/SPE) 9 | 10 | ***0xb3e7A42b647A0875682249294107Db182DDFC321*** 11 | 12 | 13 | # Funcionalidades 14 | - Farm personalizado, defina a % que suas voltam a trabalhar. 15 | - Multi Acc, logue a metamask de todas as suas contas, de play no bot e faça coisas melhores na sua vida do que ficar acordando de madrugada. :beers: 16 | - Multi OS, funciona em linux ou Windows! 17 | - Integração com Telegram, receba uma print cada X minutos, o tempo é configuravel no arquivo config.yaml. 18 | - Anti-Broken, mesmo que aconteça um erro não tratado em tela, o bot força atualização da pagina e refaz o login, reiniciando o processo de farm, no pain yes gain! 19 | - Arquivo de configuração, para que você mesmo determine como o bot deve funcionar (./config.yaml). 20 | 21 | # Como utilizar 22 | ### Requisitos: 23 | - Instalação do Python, instale pelo [site oficial](https://www.python.org/downloads/) ou pela [windows store](https://www.microsoft.com/p/python-37/9nj46sx7x90p?activetab=pivot:overviewtab) durante a instalação do python, não se esqueça de marcar a opção add Python to Path. 24 | 25 | ![Path Python](https://github.com/renatofmmaia/spacecrypto-bot/blob/main/assets/infos_and_tutorial/python_path.png) 26 | - Realizar download da ultima versão do bot em releases do repositorio github, clicando em https://github.com/renatofmmaia/spacecrypto-bot/releases 27 | - Descompactar o bot na pasta em que desejar 28 | - (Linux) Instalar o pacote xdtools (responsável por retornar as janelas de navegador no linux) através do comando: sudo apt-get install xdotool 29 | - (Linux) Instalar pacote Scrot (responsável pela printscreen no linux) através do comando: sudo apt-get install scrot 30 | 31 | ### Rodando o bot: 32 | - Abra um terminal, se for windows (aperte a tecla do windows + r e digite "cmd"). 33 | - Navegue até a pasta onde o bot foi extraído, exemplo: cd "C:\spacecrypto-bot". 34 | - Instale as dependências do bot executando o comando, sem aspas: Windows: "pip install -r requirements.txt" // Linux: "pip3 install -r requirements.txt". 35 | - **IMPORTANTE:** Seu navegador não pode estar com ZOOM, pois o bot usa reconhecimento de imagem e o tamanho e proporção dos objetos fazem diferença e deve estar sempre MAXIMIZADO, ou seja, tela cheia. 36 | - Faça o primeiro acesso na sua metamask, pois o bot realiza o login apenas se a mesma já estiver conectada. 37 | - Execute o bot executando o cmando, sem aspas: "python main.py" 38 | - Enjoy the moment :D 39 | 40 | ### Configurando o Bot 41 | - **IMPORTANTE**: Sempre que acontece um erro no bot, ele registra informações do problema no arquivo logs/logger.log, se precisar pedir alguma ajuda, não esqueça de colocar as informações que foram gravas neste arquivo. 42 | - **IMPORTANTE**: Antes de iniciar o bot, na tela de naves, selecione a opção **Max Ammo**, para que sempre as naves com mais monição sejam colocadas para cima da lista. 43 | 44 | ![max_ammo_sample](https://github.com/renatofmmaia/spacecrypto-bot/blob/main/assets/infos_and_tutorial/max_ammo_sample.png?raw=true) 45 | - Para que o bot reconheça sua resolução de tela e seja acertivo em seus comandos, você deve criar uma imagem de qualquer tela do space crypto, porém deve conter apenas a área do jogo, igual demonstrado na imagem abaixo, e salvar na pasta "assets/images/targets_global/" com o nome "screen_user.png": 46 | 47 | ![user_screen](https://github.com/renatofmmaia/spacecrypto-bot/blob/main/assets/images/targets_global/screen_full_hd.png?raw=true) 48 | ![space_user](https://github.com/renatofmmaia/spacecrypto-bot/blob/main/assets/infos_and_tutorial/space_user.png?raw=true) 49 | 50 | - **IMPORTANTE**: Após iniciar o bot, você não pode redimensionar a tela do navegador(jogo), caso seja necessário redimensionar, você deve repetir o passo acima, criando uma nova imagem da tela do space crypto. 51 | - Todas as configurações do bot são realizadas através do arquivo config.yaml 52 | - Configs importantes que você deve se atentar: 53 | ---------------------------------- 54 | - **refresh_ships** = Tempo em que o bot aguarda antes de realocar as navas para um novo farmar. 55 | - **n_ships_to_fight** = Número de naves que você quer enviar sempre que for iniciar uma nova luta com o boss. 56 | - **n_minimum_ships_to_fight** = Número minimo de naves que o bot deve aguardar, antes de iniciar uma sequência de lutas. 57 | - **ship_work_percent** = Porcentagem em que o bot vai usar como referência na hora de enviar suas naves, atualmente apenas é permitido os valores (50, 75 ou 100)%. 58 | - **repeat** = Total de scroll(rolagem) que o bot vai fazer, para encontrar as naves para farmar, a base de referência é a cada 10 naves, incrementar 4 no valor total, exemplo: 10 spaceships: 4 // 20 spaceships: 8 // 30 spaceships: 12 // ETC 59 | 60 | 61 | ### Configurando Telegram 62 | - Em seu telegram, inicie uma conversa com @BotFather 63 | - Clique em Start, e quando abrir as opções, clique em "/newbot" 64 | - Em seguida informe um nome e depois um username para o bot, lembrando que username tem que terminar com "_bot" no final, exemplo "meubomb_bot" 65 | - Finalizando você vai ver uma mensagem contendo os dados do bot que vc criou, copie o Token e insira no arquivo de configuração, config.yaml 66 | - O 2º parametro a ser configurado é o chat_id, para isso, siga os passos abaixo: 67 | - Criei um grupo no telegram, e adicione o bot que você acabou de criar, informando o username para encontra-lo. 68 | - Com o grupo criado, acesse o link a seguir, alterando o TOKEN na url, pelo o que você acabou de criar: https://api.telegram.org/botSEUTOKEN/getUpdates 69 | - Vai ser exibido na tela um JSON, procure por "chat":"id", geralmente esse valor começa com o sinal de menos(-) e altere no arquivo config.yaml chat_id. 70 | - Exemplo chat_id 71 | 72 | ![chatid](https://github.com/renatofmmaia/spacecrypto-bot/blob/main/assets/infos_and_tutorial/chat_id.png) 73 | - Config.yaml que você tem que configurar 74 | 75 | ![config trelegram](https://github.com/renatofmmaia/spacecrypto-bot/blob/main/assets/infos_and_tutorial/token_chat_id.png) 76 | 77 | ### Possíveis soluções 78 | - Mantenha a tela do navegador maximizada e a resolução do monitor preferencialmente em 1920x1080. 79 | - (linux) Muitos problemas se rolvem ao atualizar o OS, pois os pacotes da instalação são basicos para o sistema rodar, para atualizar seu linux execute o comando: ***sudo apt updade && sudo apt upgrade -y*** 80 | - (linux) Se apresentar o erro "No module named 'tkinter'", execute o comando para instalar a interface grafica do python: ***sudo apt install python3-tk*** 81 | - (linux) Caso seu linux não reconheca o comando pip ou pip3, será necessário instala-lo, através do comando: ***sudo apt install python3-pip*** 82 | 83 | # Contato/Sugestão/Bug 84 | - Issues github: https://github.com/renatofmmaia/spacecrypto-bot/issues/new 85 | 86 | -------------------------------------------------------------------------------- /module/image.py: -------------------------------------------------------------------------------- 1 | from os import listdir, path, mkdir 2 | from turtle import width 3 | 4 | import mss 5 | import numpy as np 6 | import PIL.Image 7 | from cv2 import cv2 8 | 9 | from .config import Config 10 | from .logger import logger 11 | from .utils import * 12 | 13 | 14 | class Image: 15 | TARGETS = [] 16 | TARGETS_GLOBAL = [] 17 | MONITOR_LEFT = None 18 | MONITOR_TOP = None 19 | TARGETS_DIR = None 20 | SCREEN_REFERENCE = None 21 | 22 | def load_targets_global(): 23 | path = "assets/images/targets_global/" 24 | file_names = listdir(path) 25 | 26 | targets = {} 27 | for file in file_names: 28 | targets[replace(file, ".png")] = cv2.imread(path + file) 29 | 30 | Image.TARGETS_GLOBAL = targets 31 | 32 | def load_targets_default(): 33 | Image.set_best_targets_to_use() 34 | path = f"assets/images/{Image.TARGETS_DIR}/" 35 | file_names = listdir(path) 36 | 37 | targets = {} 38 | for file in file_names: 39 | targets[replace(file, ".png")] = cv2.imread(path + file) 40 | 41 | Image.TARGETS = targets 42 | 43 | def load_targets_user(): 44 | Image.set_images_resolution() 45 | path = f"assets/images/targets_user/" 46 | file_names = listdir(path) 47 | 48 | Image.TARGETS = [] 49 | targets = {} 50 | for file in file_names: 51 | targets[replace(file, ".png")] = cv2.imread(path + file) 52 | 53 | Image.TARGETS = targets 54 | 55 | def screen(): 56 | with mss.mss() as sct: 57 | monitor = sct.monitors[0] 58 | sct_img = np.array(sct.grab(monitor)) 59 | Image.MONITOR_LEFT = monitor["left"] 60 | Image.MONITOR_TOP = monitor["top"] 61 | return sct_img[:, :, :3] 62 | 63 | def get_monitor_with_target(target): 64 | position_bomb = Image.get_one_target_position(target, 0) 65 | with mss.mss() as sct: 66 | monitors = sct.monitors 67 | 68 | for monitor in monitors: 69 | if len(monitors) == 1: 70 | return monitor.values() 71 | if Image.position_inside_position(position_bomb, monitor.values()): 72 | return monitor.values() 73 | 74 | return monitors[0] 75 | 76 | def get_compare_result(img1, img2): 77 | return cv2.matchTemplate(img1, img2, cv2.TM_CCOEFF_NORMED) 78 | 79 | 80 | def position_inside_position(position_in, position_out): 81 | x_in,y_in,w_in,h_in = position_in 82 | x_out,y_out,w_out,h_out = position_out 83 | 84 | start_inside_x = x_out <= x_in <= (x_out+w_out) 85 | finish_inside_x = x_out <= x_in + w_in <= (x_out + w_out) 86 | start_inside_y = y_out <= y_in <= (y_out+h_out) 87 | finish_inside_y = y_out <= y_in + h_in <= (y_out + h_out) 88 | 89 | return start_inside_x and finish_inside_x and start_inside_y and finish_inside_y 90 | 91 | 92 | def print_full_screen(image_name: str): 93 | image_name = f'{image_name}.png' 94 | image = pyautogui.screenshot() 95 | image.save(image_name) 96 | return image_name 97 | 98 | def print_partial_screen(image_name: str, target: str): 99 | image_name = f'{image_name}.png' 100 | x,y,w,h = Image.get_one_target_position(target, 0) 101 | image = pyautogui.screenshot(region=(x,y,w,h)) 102 | image.save(image_name) 103 | return image_name 104 | 105 | def get_target_positions(target:str, screen_image = None, threshold:float=0.8, not_target:str=None): 106 | threshold_config = Config.PROPERTIES["threshold"]["to_work"] 107 | if(threshold_config): 108 | threshold = threshold_config 109 | 110 | target_img = Image.TARGETS[target] 111 | height, width = target_img.shape[:2] 112 | 113 | screen_img = Image.screen() if screen_image is None else screen_image 114 | result = cv2.matchTemplate(screen_img, target_img, cv2.TM_CCOEFF_NORMED) 115 | 116 | if not_target is not None: 117 | not_target_img = Image.TARGETS[not_target] 118 | not_target_result = cv2.matchTemplate(screen_img, not_target_img, cv2.TM_CCOEFF_NORMED) 119 | result[result < not_target_result] = 0 120 | 121 | y_result, x_result = np.where( result >= threshold) 122 | 123 | results_len = len(x_result) 124 | del_index = [] 125 | for i in range(1, results_len): 126 | x = x_result[i] 127 | y = y_result[i] 128 | x_range = x_result[i-1], x_result[i-1]+width 129 | y_range = y_result[i-1], y_result[i-1]+height 130 | 131 | if x_range[0] <= x <= x_range[1] and y_range[0] <= y <= y_range[1]: 132 | del_index.append(i) 133 | 134 | y_result = np.delete(y_result, del_index) 135 | x_result = np.delete(x_result, del_index) 136 | 137 | 138 | targets_positions = [] 139 | for (x,y) in zip(x_result, y_result): 140 | x += Image.MONITOR_LEFT 141 | y += Image.MONITOR_TOP 142 | targets_positions.append([x,y,width,height]) 143 | 144 | return targets_positions 145 | 146 | def get_first_target_position(target:str, screen_image = None, threshold:float=0.8, not_target:str=None): 147 | positions = Image.get_target_positions(target, screen_image, threshold, not_target) 148 | if len(positions) == 0: 149 | return None 150 | return positions[0] 151 | 152 | def get_one_target_position(target:str, threshold:float=0.8, target_global = False, screen_image = None): 153 | threshold_config = Config.get("threshold", "default") 154 | if(threshold_config): 155 | threshold = threshold_config 156 | 157 | target_img = Image.TARGETS_GLOBAL[target] if target_global else Image.TARGETS[target] 158 | screen_img = Image.screen() if screen_image is None else screen_image 159 | result = cv2.matchTemplate(screen_img, target_img, cv2.TM_CCOEFF_NORMED) 160 | 161 | if result.max() < threshold: 162 | raise Exception(f"{target} not found") 163 | 164 | yloc, xloc = np.where(result == result.max()) 165 | xloc += Image.MONITOR_LEFT 166 | yloc += Image.MONITOR_TOP 167 | height, width = target_img.shape[:2] 168 | 169 | return xloc[0], yloc[0], width, height 170 | 171 | def get_max_result_between(targets:list, y_limits=None, x_limits=None, threshold:float=0, screen_img=None): 172 | index = 0 173 | max_result = 0 174 | for i, target in enumerate(targets): 175 | screen = Image.screen() if screen_img is None else screen_img 176 | if y_limits is not None: 177 | screen= screen[y_limits[0]:y_limits[1], :] 178 | if x_limits is not None: 179 | x,w = x_limits 180 | screen= screen[:, x:x+w] 181 | result = cv2.matchTemplate(screen, Image.TARGETS[target], cv2.TM_CCOEFF_NORMED) 182 | if result.max() > max_result: 183 | max_result = result.max() 184 | index = i 185 | 186 | return index 187 | 188 | 189 | def filter_by_green_bar(item): 190 | x,y,w,h = item 191 | y_increment = round(h*0.1) 192 | screen_img = Image.screen()[y:y+h+y_increment,:] 193 | result = Image.get_target_positions("hero_bar_green", screen_image=screen_img) 194 | return len(result) > 0 195 | 196 | def set_images_resolution(): 197 | im_fh = np.array(Image.TARGETS_GLOBAL[Image.SCREEN_REFERENCE]) 198 | diag_fh = (im_fh.shape[0]**2 + im_fh.shape[1]**2)**0.5 199 | 200 | im_user = np.array(Image.TARGETS_GLOBAL['screen_user']) 201 | diag_user = (im_user.shape[0]**2 + im_user.shape[1]**2)**0.5 202 | 203 | user_interface_percent = (diag_user / diag_fh) 204 | 205 | path_user_by_resolution = f'./assets/images/targets_user' 206 | 207 | if not path.exists(path_user_by_resolution): 208 | mkdir(path_user_by_resolution) 209 | 210 | for image_name in Image.TARGETS: 211 | image = PIL.Image.open(f'./assets/images/{Image.TARGETS_DIR}/{image_name}.png') 212 | h = round(np.array(image).shape[0] * user_interface_percent) 213 | w = round(np.array(image).shape[1] * user_interface_percent) 214 | image = image.resize((w,h), PIL.Image.ANTIALIAS) 215 | image.save(f'{path_user_by_resolution}/{image_name}.png') 216 | 217 | def set_best_targets_to_use(): 218 | user = np.array(Image.TARGETS_GLOBAL['screen_user']) 219 | diag_user = (user.shape[0]**2 + user.shape[1]**2)**0.5 220 | 221 | hd = np.array(Image.TARGETS_GLOBAL['screen_full_hd']) 222 | diag_hd = (hd.shape[0]**2 + hd.shape[1]**2)**0.5 223 | 224 | hd_ratio = diag_user / diag_hd 225 | 226 | if hd_ratio > 1.05: 227 | Image.TARGETS_DIR = 'targets_hd' 228 | Image.SCREEN_REFERENCE = 'screen_hd' 229 | else : 230 | Image.TARGETS_DIR = 'targets' 231 | Image.SCREEN_REFERENCE = 'screen_full_hd' -------------------------------------------------------------------------------- /module/spaceScreen.py: -------------------------------------------------------------------------------- 1 | from distutils.command.config import config 2 | from email.mime import image 3 | from enum import Enum 4 | from re import search 5 | from tkinter.tix import IMAGE 6 | from turtle import Screen 7 | 8 | 9 | from cv2 import cv2 10 | 11 | from .config import Config 12 | from .image import Image 13 | from .logger import LoggerEnum, logger, logger_translated 14 | from .mouse import * 15 | from .utils import * 16 | from .telegram import TelegramBot 17 | class SpaceScreenEnum(Enum): 18 | POPUP_ERROR = -2 19 | NOT_FOUND = -1 20 | LOGIN = 0 21 | HOME = 1 22 | SHIP = 2 23 | FIGHT = 3 24 | BASE = 4 25 | LOSE = 5 26 | VICTORY = 6 27 | 28 | 29 | class SpaceScreen: 30 | def wait_for_screen( 31 | spaceScreenEnum, time_beteween: float = 0.5, timeout: float = 60 32 | ): 33 | def check_screen(): 34 | screen = SpaceScreen.get_current_screen() 35 | if screen == spaceScreenEnum: 36 | return True 37 | else: 38 | return None 39 | res = do_with_timeout( 40 | check_screen, time_beteween=time_beteween, timeout=timeout 41 | ) 42 | 43 | if res is None: 44 | raise Exception(f'Timeout waiting for screen {SpaceScreenEnum(spaceScreenEnum).name}.') 45 | 46 | return res 47 | 48 | def wait_for_possible_screen( 49 | spaceScreenEnums: list, time_beteween: float = 0.5, timeout: float = 15 50 | ): 51 | def check_screen(): 52 | screen = SpaceScreen.get_current_screen() 53 | 54 | if SpaceScreenEnum(screen) in spaceScreenEnums: 55 | return screen 56 | else: 57 | return None 58 | res = do_with_timeout( 59 | check_screen, time_beteween=time_beteween, timeout=timeout 60 | ) 61 | 62 | if res is None: 63 | screen_names = ", ".join([space_screen.name for space_screen in spaceScreenEnums]) 64 | raise Exception(f'Timeout waiting for one of screens: {screen_names}.') 65 | 66 | return res 67 | 68 | def wait_for_leave_screen( 69 | spaceScreenEnum, time_beteween: float = 0.5, timeout: float = 60 70 | ): 71 | def check_screen(): 72 | screen = SpaceScreen.get_current_screen() 73 | if screen == spaceScreenEnum: 74 | return None 75 | else: 76 | return True 77 | 78 | return do_with_timeout( 79 | check_screen, time_beteween=time_beteween, timeout=timeout 80 | ) 81 | 82 | 83 | def get_current_screen(time_beteween: float = 0.5, timeout: float = 20): 84 | targets = { 85 | SpaceScreenEnum.HOME.value: Image.TARGETS["identify_home"], 86 | SpaceScreenEnum.LOSE.value: Image.TARGETS["identify_lose"], 87 | SpaceScreenEnum.FIGHT.value: Image.TARGETS["identify_hunting"], 88 | SpaceScreenEnum.BASE.value: Image.TARGETS["identify_base"], 89 | SpaceScreenEnum.VICTORY.value: Image.TARGETS["identify_victory"], 90 | SpaceScreenEnum.LOGIN.value: Image.TARGETS["identify_login"], 91 | SpaceScreenEnum.POPUP_ERROR.value: Image.TARGETS["popup_erro"], 92 | } 93 | max_value = 0 94 | img = Image.screen() 95 | screen_name = -1 96 | 97 | for name, target_img in targets.items(): 98 | result = cv2.matchTemplate(img, target_img, cv2.TM_CCOEFF_NORMED) 99 | max_value_local = result.max() 100 | if max_value_local > max_value: 101 | max_value = max_value_local 102 | screen_name = name 103 | 104 | return screen_name if max_value > Config.get("threshold", "default") else -1 105 | 106 | def go_to_home(manager): 107 | current_screen = SpaceScreen.get_current_screen() 108 | if current_screen == SpaceScreenEnum.HOME.value: 109 | return 110 | elif current_screen == SpaceScreenEnum.LOSE.value: 111 | click_when_target_appears("button_confirm_without_time") 112 | SpaceScreen.wait_for_screen(SpaceScreenEnum.FIGHT.value) 113 | SpaceScreen.go_to_home(manager) 114 | elif current_screen == SpaceScreenEnum.FIGHT.value: 115 | logger_translated("Space Ships", LoggerEnum.BUTTON_CLICK) 116 | if not click_when_target_appears("button_hunt_ships"): 117 | Login.do_login(manager) 118 | elif current_screen == SpaceScreenEnum.BASE.value: 119 | logger_translated("Space Ships", LoggerEnum.BUTTON_CLICK) 120 | click_when_target_appears("button_spaceship_home") 121 | SpaceScreen.wait_for_screen(SpaceScreenEnum.HOME.value) 122 | elif current_screen == SpaceScreenEnum.VICTORY.value: 123 | logger_translated("Confirm", LoggerEnum.BUTTON_CLICK) 124 | click_when_one_of_targets_appears(["btn_confirm_gt_10s", "btn_confirm_lt_9s"]) 125 | SpaceScreen.wait_for_screen(SpaceScreenEnum.FIGHT.value) 126 | SpaceScreen.go_to_home(manager) 127 | else: 128 | Login.do_login(manager) 129 | return 130 | 131 | SpaceScreen.wait_for_screen(SpaceScreenEnum.HOME.value) 132 | 133 | def go_to_fight(manager): 134 | current_screen = SpaceScreen.get_current_screen() 135 | if current_screen == SpaceScreenEnum.FIGHT.value: 136 | return 137 | elif current_screen == SpaceScreenEnum.LOSE.value: 138 | click_when_target_appears("button_confirm_without_time") 139 | else: 140 | SpaceScreen.go_to_home(manager) 141 | click_when_target_appears("btn_fight_boss") 142 | 143 | new_screen = SpaceScreen.wait_for_possible_screen([ 144 | SpaceScreenEnum.FIGHT, 145 | SpaceScreenEnum.LOSE, 146 | ]) 147 | if new_screen == SpaceScreenEnum.LOSE.value: 148 | SpaceScreenEnum.go_to_fight(manager) 149 | 150 | def do_print_token(manager): 151 | logger_translated("print token", LoggerEnum.ACTION) 152 | image = None 153 | 154 | try: 155 | image = Image.print_full_screen("print") 156 | TelegramBot.send_message_with_image(image, "Family JOW, não deixe de contribuir com a evolução do bot :D") 157 | except Exception as e: 158 | logger(str(e)) 159 | logger("😬 Ohh no! We couldn't send your farm report to Telegram.", color="yellow", force_log_file=True) 160 | 161 | manager.set_refresh_timer("refresh_print_token") 162 | 163 | class Login: 164 | def do_login(manager): 165 | current_screen = SpaceScreen.get_current_screen() 166 | logged = False 167 | 168 | if current_screen != SpaceScreenEnum.LOGIN.value and current_screen != SpaceScreenEnum.NOT_FOUND.value and current_screen != SpaceScreenEnum.POPUP_ERROR.value: 169 | logged = True 170 | 171 | if not logged: 172 | logger_translated("login", LoggerEnum.ACTION) 173 | 174 | login_attepmts = Config.PROPERTIES["screen"]["number_login_attempts"] 175 | 176 | for i in range(login_attepmts): 177 | 178 | if SpaceScreen.get_current_screen() != SpaceScreenEnum.LOGIN.value: 179 | refresh_page() 180 | SpaceScreen.wait_for_screen(SpaceScreenEnum.LOGIN.value) 181 | 182 | logger_translated("Login", LoggerEnum.PAGE_FOUND) 183 | 184 | logger_translated("wallet", LoggerEnum.BUTTON_CLICK) 185 | if not click_when_target_appears("button_connect_wallet"): 186 | refresh_page() 187 | continue 188 | 189 | logger_translated("sigin wallet", LoggerEnum.BUTTON_CLICK) 190 | if not click_when_target_appears("button_connect_wallet_sign", target_global=True): 191 | refresh_page() 192 | continue 193 | 194 | logger_translated("play", LoggerEnum.BUTTON_CLICK) 195 | if not click_when_target_appears("button_connect_wallet_play"): 196 | refresh_page() 197 | continue 198 | 199 | if (SpaceScreen.wait_for_screen(SpaceScreenEnum.HOME.value) != SpaceScreenEnum.HOME.value): 200 | logger("🚫 Failed to login, restart proccess...") 201 | continue 202 | else: 203 | logger("🎉 Login successfully!") 204 | logged = True 205 | break 206 | 207 | return logged 208 | 209 | class Ship: 210 | def do_check_error(manager): 211 | current_screen = SpaceScreen.get_current_screen() 212 | 213 | if current_screen == SpaceScreenEnum.POPUP_ERROR.value or current_screen == SpaceScreenEnum.NOT_FOUND.value: 214 | logger_translated("Check screen error found, restarting...", LoggerEnum.ERROR) 215 | Login.do_login(manager) 216 | 217 | if manager.is_fighting: 218 | SpaceScreen.go_to_fight(manager) 219 | 220 | manager.set_refresh_timer("refresh_check_error") 221 | 222 | def keep_working(manager): 223 | logger_translated(f"Ships keeping work", LoggerEnum.ACTION) 224 | 225 | current_screen = SpaceScreen.get_current_screen() 226 | 227 | if current_screen != SpaceScreenEnum.HOME.value: 228 | SpaceScreen.go_to_home(manager) 229 | 230 | Ship.remove_ships() 231 | 232 | scale_factor = 25 233 | ship_bar = [ 234 | "ship_bar_50", "ship_bar_75", "ship_bar_100" 235 | ] 236 | 237 | if current_screen == SpaceScreenEnum.FIGHT.value: 238 | return True 239 | 240 | scroll_times=0 241 | n_ships = 0 242 | 243 | def click_first(btns_pos, search_img): 244 | for button_position in btns_pos: 245 | x,y,w,h = button_position 246 | initial_y = y + h - height_search_area - Image.MONITOR_TOP 247 | final_y = initial_y + height_search_area 248 | 249 | search_bar_img = search_img[initial_y:final_y, :, :] 250 | 251 | life_max_values = [Image.get_compare_result(search_bar_img, Image.TARGETS[bar]).max() for bar in ship_bar] 252 | life_index, life_max_value= 0, 0 253 | for i, value in enumerate(life_max_values): 254 | life_index, life_max_value = (i, value) if value >= life_max_value else (life_index, life_max_value) 255 | 256 | ship_life = 50 + (life_index * scale_factor) 257 | 258 | logger(f"↳ {ship_life}%", end=" ", datetime=False) 259 | 260 | if ship_life >= ship_work_percent: 261 | click_randomly_in_position(x,y,w,h) 262 | logger("💪;", datetime=False) 263 | return True 264 | else: 265 | logger("💤;", datetime=False) 266 | 267 | return False 268 | 269 | logger(f"Sending ships to fight:") 270 | 271 | while scroll_times <= (Config.get('screen','scroll', 'repeat')): 272 | if n_ships >= Config.get('n_ships_to_fight'): 273 | break 274 | 275 | screen_img = Image.screen() 276 | 277 | buttons_position = Image.get_target_positions("button_fight_on", not_target="button_fight_off", screen_image=screen_img) 278 | 279 | if not buttons_position: 280 | Ship.scroll_ships() 281 | scroll_times += 1 282 | continue 283 | 284 | x_buttons, _, w_buttons, _ = buttons_position[0] 285 | height_search_area, width_search_area = Image.TARGETS["ship_search_area"].shape[:2] 286 | inital_x = x_buttons + w_buttons - width_search_area - Image.MONITOR_LEFT 287 | final_x = inital_x + width_search_area 288 | 289 | search_img = screen_img[:,inital_x:final_x, :] 290 | 291 | 292 | ship_work_percent = Config.get('ship_work_percent') 293 | 294 | if click_first(buttons_position, search_img): 295 | n_ships +=1 296 | time.sleep(0.5) 297 | # start_time = time.time() 298 | # while not Ship.check_number_of_ships(Image.screen(), n_ships): 299 | # if time.time() - start_time > 15: 300 | # if not Ship.check_number_of_ships(Image.screen(), n_ships): 301 | # raise Exception(f"Error trying to send {n_ships} ships to fight.") 302 | else: 303 | Ship.scroll_ships() 304 | scroll_times += 1 305 | continue 306 | 307 | 308 | 309 | if n_ships < Config.get('n_minimum_ships_to_fight'): 310 | logger(f"🚫 Not enough ships to fight, restarting minutes...") 311 | Ship.remove_ships() 312 | manager.set_recharge() 313 | SpaceScreen.go_to_fight(manager) 314 | SpaceScreen.go_to_home(manager) 315 | manager.set_refresh_timer("refresh_ships") 316 | logger(f"🚫 Waiting for {Config.get('refresh_ships')} minutes to reset proccess, config(refresh_ships).") 317 | return False 318 | 319 | click_when_target_appears('btn_fight_boss') 320 | current_screen = SpaceScreen.wait_for_possible_screen([ 321 | SpaceScreenEnum.FIGHT, 322 | SpaceScreenEnum.LOSE, 323 | ]) 324 | if current_screen == SpaceScreenEnum.LOSE.value: 325 | click_when_target_appears('button_confirm_without_time', 10) 326 | 327 | logger(f"🚀 {n_ships} new ships sent to explode the boss 💣💣💣.") 328 | manager.set_fighting() 329 | manager.set_refresh_timer("refresh_ships") 330 | return True 331 | 332 | def scroll_ships(): 333 | return scroll( 334 | safe_scroll_target=["button_fight_on", "button_fight_off"], 335 | distance=Config.get('screen','scroll', 'distance'), 336 | duration=Config.get('screen','scroll', 'duration'), 337 | wait=Config.get('screen','scroll', 'wait'), 338 | ) 339 | 340 | def check_number_of_ships(screen_img, n_ships): 341 | # CROP SCREEN FROM TEXT 'BATTLE': 342 | x, y, w, h = Image.get_one_target_position("identify_n_space_shipts_in_battle_start_area", screen_image=screen_img) 343 | y_i = y - Image.MONITOR_TOP 344 | y_f = y_i + h 345 | x_i = x + w - Image.MONITOR_LEFT 346 | search_img = screen_img[y_i:y_f, x_i:] 347 | 348 | # CROP SCREEN BEFORE TEXT '/15': 349 | x, y, w, h = Image.get_one_target_position("identify_n_space_shipts_in_battle_end_area", screen_image=search_img) 350 | x_f = x - Image.MONITOR_LEFT 351 | search_img = search_img[:, :x_f] 352 | 353 | # SEARCH N SHIPS: 354 | # n_ships_list = [f"{i}_ships_in_battle" for i in range(16)] 355 | try: 356 | Image.get_one_target_position(f"{n_ships}_ships_in_battle", screen_image=search_img) 357 | return True 358 | except: 359 | return False 360 | 361 | 362 | def remove_ships(): 363 | screen_img = Image.screen() 364 | x, y, w, h = Image.get_one_target_position("btn_fight_boss", screen_image=screen_img) 365 | height_search_area, width_search_area = Image.TARGETS["identify_n_space_shipts_in_battle_board"].shape[:2] 366 | y_i = y - height_search_area - Image.MONITOR_TOP 367 | y_f = y_i + height_search_area 368 | x_i = x - Image.MONITOR_LEFT 369 | x_f = x_i + width_search_area 370 | search_img = screen_img[y_i:y_f, x_i:x_f] 371 | targets_positions = Image.get_target_positions('button_ship_x', screen_image=search_img) 372 | for target_position in targets_positions[::-1]: 373 | x, y, w, h = target_position 374 | x += x_i 375 | y += y_i 376 | click_randomly_in_position(x,y,w,h) 377 | 378 | if len(targets_positions) > 0: 379 | Ship.remove_ships() 380 | 381 | def check_lose(manager): 382 | current_screen = SpaceScreen.get_current_screen() 383 | if current_screen == SpaceScreenEnum.LOSE.value: 384 | SpaceScreen.go_to_home(manager) 385 | Ship.remove_ships() 386 | manager.set_recharge() 387 | 388 | def check_victory(manager): 389 | current_screen = SpaceScreen.get_current_screen() 390 | if current_screen == SpaceScreenEnum.VICTORY.value: 391 | click_when_one_of_targets_appears(["btn_confirm_gt_10s", "btn_confirm_lt_9s"]) 392 | SpaceScreen.wait_for_screen(SpaceScreenEnum.FIGHT.value) 393 | --------------------------------------------------------------------------------