main 117d64e1b396 cached
14 files
35.2 KB
9.3k tokens
70 symbols
1 requests
Download .txt
Repository: cryptotwinsbr/spacecrypto-bot
Branch: main
Commit: 117d64e1b396
Files: 14
Total size: 35.2 KB

Directory structure:
gitextract_4c99dw9i/

├── .gitignore
├── README.md
├── bomb_settings.yaml
├── bomberland-bot.py
├── debug.py
├── modules/
│   ├── bombScreen.py
│   ├── config.py
│   ├── imageBomb.py
│   ├── managerBomb.py
│   ├── mouseBomb.py
│   ├── platform.py
│   ├── utils.py
│   └── window.py
└── requirements.txt

================================================
FILE CONTENTS
================================================

================================================
FILE: .gitignore
================================================
# IDE
.vim

# log
/logs/new-map.log
/logs/logger.log
logs/

# cache
/src/__pycache__
/captcha/__pycache__
debug.log
rewards.log

# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class


================================================
FILE: README.md
================================================
# 🚀 Bomber Land Crypto auto click bot ready-to-use 🚀

![image](https://github.com/cryptotwinsbr/bomberland-bot/assets/26221704/b66ad7c3-9c25-4f03-bedc-3499ea860f0a)


[![Author](https://img.shields.io/badge/author-cryptotwins-blue)]() ![python](https://img.shields.io/badge/python-%5E%203-green) 

This is a free python bot program that crosses you to farm with auto click in bomber land crypto NFT game, having fun :)


# Updates para versão 2024 lançada

- Arquivo para selecionar rede BSC/Polygon

- Ativação do farm automatico.


#e para quem for copiar e colar nosso código pelo menos manda um salve no video :clown: 


---
## About Project


This is a open source project inpired to help the comunnity of bomberland version 2024.

To maintain the improvments and this auto click bot free, please help me with any value, have fun :)

- Metamask wallet (BNB/BUSD/BCOIN/BOMB/SENS):  `0x73933b679F940ea7352c3895852501e3044FE855`
- My key pix: `5f3d220c-a2a3-4db2-bfb2-30ae0533e240`

QRCode pix:

![image](https://user-images.githubusercontent.com/98666682/151678042-ad125099-297c-4c5d-a5f3-92b083733b55.png)


Feel free to give your feedback ;)
---
We added a folder (screen_test) with images that you can test the bot, just open the image with your bot active.

*Observation: we reccomend to use just 1 screen to have a bot totally functional

## Warning

We are not responsible for any penalties incurred by those who use the autoclick bot, use at your own risk.

## Aviso 

Nós não nos responsabilizarmos por eventuais penalidades sofridas por quem usar o bot de autoclick, use por sua própria conta e risco.

---
## Summary

<!--ts-->

- [About Project](#about-project)
- [Software Requirements](#software-requirements)
- [How to Run](#how-to-run)
  - [Install dependencies](#install-dependencies)
  - [Run auto click bot](#run-auto-click-bot)
- [Thank you](#thank-you)
  <!--te-->
  </br>


## Software Requirements

- PYTHON **3+**
  </br>


## How to run

### Install dependencies

In order for you to run, you need to install the dependencies in advance. 

Download [python site](https://www.python.org/downloads/) 

![image](https://user-images.githubusercontent.com/98666682/151677437-87fea683-60dd-495a-a2e4-4ec28bb7a04c.png)

In the installation check the option and complete the install.

![image](https://user-images.githubusercontent.com/98666682/151677529-96ed2731-3ac9-412c-bd7f-9b629cee8ebb.png)


Download the project on your machine

Extract your zip and copy the directory


### Run auto click bot

After install and download the dependences, run the following commands:


```bash
# Access tha project folder:
 cd <path copyed before> 
 Sample:
 cd C:\<your path here>\bomberland-bot-main
```


Install the dependences, execute this commands:

````bash
# It will run
pip install -r requirements.txt
````

Now you just need to run by following the command:

````bash
# run the auto click bot
python bomberland-bot.py
````


</br>

### Thank you! 

I hope it can help you, don't forget to strengthen it by making a donation :) any amount helps us to keep updated to help you in the best way

- Metamask wallet (BNB/SPG/BUSD/BCOIN):  `0x73933b679F940ea7352c3895852501e3044FE855`
- My key pix: `5f3d220c-a2a3-4db2-bfb2-30ae0533e240`

QRCode pix:

![image](https://user-images.githubusercontent.com/98666682/151678042-ad125099-297c-4c5d-a5f3-92b083733b55.png)

![Alt](https://repobeats.axiom.co/api/embed/ddb8ac3538f8d752e9da228f87583fcf646d93be.svg "Repobeats analytics image")


Have a nice farm and a good sleep night! :)

</br>
</br>


================================================
FILE: bomb_settings.yaml
================================================
generals:
  # Save all logs in file logs/logger.txt
  #   0: Don't save log
  #   1: Save log
  save_log_file: 0
  
  # Reset log file on start
  #   0: false
  #   1: true
  reset_log_file: 1

  # Which hotkey is used to refresh the browser
  #   1: CTRL + F5
  #   2: CTRL + SHIFT + R
  refresh_page_shortcut: 1
  # Time format to show on logs:
  # Full date time: "%Y-%m-%d %H:%M:%S"
  time_format: "%m-%d %H:%M"


heroes_work_mod:
  # Properties that identifies heroes to work according rarity and life %;
  #   Available options: 0, 10, 20, 30, 40, 50, 60, 70, 80, 90 or 100.
  Common: 60
  Rare: 40
  SuperRare: 30
  Epic: 30
  Legend: 30
  SuperLegend: 30


screen:
  # Number of login attempts
  number_login_attempts: 3

  # Time to update hero positions on farm screen
  refresh_hunt: 3

  # Timer to check who needs to go back to work
  refresh_heroes: 20

  # Timer to force browser refresh, prevent indestructible blocks and other possibles errors
  refresh_login: 45

  # Timer to check popup screen errors, if it's in error, restarts with login again
  refresh_check_error: 1

  # Chest photo type, for sending via Telegram
  #   true: The entire screen where the browser tab will be
  #   false: Just chest screen with your coins
  print_full_screen: false

  scroll_heroes:
    # total number of times the screen scrolls down
    repeat: 3

    # distance when scrolling down
    distance: -375

    # duration of scrolling
    duration: 2 

    # Wait time to stop scrolling before checking the heroes on the screen.
    wait: 1

telegram:
  # Settings for telegram integration 
  token: ""
  chat_id: 0

  # Timer when your chest image is sent to telegram
  refresh_print_chest: 60
  

# xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# DONT CHANGE THIS CONFIGS
# ------------------------
threshold:
  default: 0.7
  hero_to_work: 0.9
# xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

================================================
FILE: bomberland-bot.py
================================================
# -*- coding: utf-8 -*-    
import pyautogui
import sys
import time
from debug import Debug
import yaml
from modules.config import Config
from modules.bombScreen import BombScreen
from modules.managerBomb import create_bombcrypto_managers
from modules.imageBomb import ImageBomb

VERSAO_SCRIPT = "2.00"
dbg = Debug('debug.log')

str_in = """
            ░░░░░░░█▐▓▓░████▄▄▄█▀▄▓▓▓▌█
            ░░░░░▄█▌▀▄▓▓▄▄▄▄▀▀▀▄▓▓▓▓▓▌█
            ░░░▄█▀▀▄▓█▓▓▓▓▓▓▓▓▓▓▓▓▀░▓▌█
            ░░█▀▄▓▓▓███▓▓▓███▓▓▓▄░░▄▓▐█▌
            ░█▌▓▓▓▀▀▓▓▓▓███▓▓▓▓▓▓▓▄▀▓▓▐█
            ▐█▐██▐░▄▓▓▓▓▓▀▄░▀▓▓▓▓▓▓▓▓▓▌█▌
            █▌███▓▓▓▓▓▓▓▓▐░░▄▓▓███▓▓▓▄▀▐█
            █▐█▓▀░░▀▓▓▓▓▓▓▓▓▓██████▓▓▓▓▐█
            ▌▓▄▌▀░▀░▐▀█▄▓▓██████████▓▓▓▌█▌
            ▌▓▓▓▄▄▀▀▓▓▓▀▓▓▓▓▓▓▓▓█▓█▓█▓▓▌█▌
            █▐▓▓▓▓▓▓▄▄▄▓▓▓▓▓▓█▓█▓█▓█▓▓▓▐█ 
    +++++++++++++++++++++++++++++++++++++++++++++++
    +++ 🌙 Melhorando nossas noites de sono 🌙 +++
    +++ Se te ajudamos, por favor contribua 😊🚀++
    +++++++++++ BCOIN BOMB SEN BUSD BNB +++++++++++
    + 0x73933b679F940ea7352c3895852501e3044FE855 ++
    ++++++++++++++++ Pix key ++++++++++++++++++++++
    ++++ 5f3d220c-a2a3-4db2-bfb2-30ae0533e240 +++++

    * Algumas configurações podem ser alteradas em 
    bomb_settings.yaml

    >> Ctrl + c finaliza o bot.
    
    
    """

def main():
    try:
        print(str_in)        
        time.sleep(5)
        dbg.console('Bot Iniciado. Versao: ' + str(VERSAO_SCRIPT), 'INFO', 'ambos', 'ALL')

        config_file = "bomb_settings.yaml"
        Config.load_config(config_file)
        ImageBomb.load_targets()
        bomb_crypto_managers = create_bombcrypto_managers()
        dbg.console("Contas BombCryto encontradas: " + str(len(bomb_crypto_managers)), 'INFO', 'ambos', 'BOMB')
        bomb_browser_count = 1
        show_initial = True

        while True:
            try:
                for manager in bomb_crypto_managers:
                    current_screen = BombScreen.get_current_screen()
                    
                    if show_initial:
                        dbg.console("Tela BombCrypto: " + str(bomb_browser_count), "INFO", "ambos", "BOMB:" + str(bomb_browser_count))
                    
                    with manager:
                        manager.do_what_needs_to_be_done(current_screen, bomb_browser_count)
                    
                    if bomb_browser_count == len(bomb_crypto_managers):
                        bomb_browser_count = 1
                        show_initial = False
                    else:
                        bomb_browser_count += 1
            except Exception as e:
                dbg.console("Except bombcrypto: " + str(e), "WARNING", "ambos", 'BOMB')      
        time.sleep(5)
    except Exception as e:
        dbg.console("Erro ao iniciar o bot. Erro: " + str(e), "ERROR", "ambos", 'ALL')

if __name__ == '__main__':
    main()

================================================
FILE: debug.py
================================================
import time
import datetime
import threading
import logging

class Debug:
    def __init__(self, filename):
        self.filename = filename
        # Configuracao basica do logging
        logging.basicConfig(
        filename=self.filename,
        filemode='a+',
        level=logging.DEBUG,
        format='[%(asctime)s] [%(levelname)s] [%(threadName)-10s] %(message)s',
        datefmt='%Y-%b-%d %H:%M:%S'
        )
        
    def console(self, msg, level, destino, type):        
        hora_rede_local = time.strftime("%H:%M:%S", time.localtime())
        self.msg = msg
        self. level= level
        self.destino = destino
        if self.destino == 'monitor':
            print('[{} {}][{}][{}] {}'.format(datetime.date.today(), hora_rede_local, type, level, msg)) 
        elif self.destino == 'arquivo':
            if self.level == 'DEBUG':
                logging.debug(msg)
            elif self.level == 'INFO':
                logging.info(msg)
            elif self.level == 'WARNING':
                logging.warn(msg)
            elif self.level == 'ERROR':
                logging.error(msg)
            elif self.level == 'CRITICAL':
                logging.critical(msg)
        elif self.destino == 'ambos':    
            print('[{} {}][{}][{}] {}'.format(datetime.date.today(), hora_rede_local, type, level, msg)) 
            if self.level == 'DEBUG':
                logging.debug(msg)
            elif self.level == 'INFO':
                logging.info(msg)
            elif self.level == 'WARNING':
                logging.warn(msg)
            elif self.level == 'ERROR':
                logging.error(msg)
            elif self.level == 'CRITICAL':
                logging.critical(msg)

================================================
FILE: modules/bombScreen.py
================================================
from enum import Enum
from cv2 import cv2
from .config import Config
from .imageBomb import ImageBomb
from .mouseBomb import *
from .utils import *
from debug import Debug

dbg = Debug('debug.log')

class BombScreenEnum(Enum):
    NOT_FOUND = -1
    LOGIN = 0
    HOME = 1
    HEROES = 2
    TREASURE_HUNT = 3
    CHEST = 4
    POPUP_ERROR = 5
    SETTINGS = 6

class BombScreen:
    def wait_for_screen(
        bombScreenEnum, time_beteween: float = 0.5, timeout: float = 60
    ):
        def check_screen():
            screen = BombScreen.get_current_screen()
            if screen == bombScreenEnum:
                return True
            else:
                return None
        res = do_with_timeout(
            check_screen, time_beteween=time_beteween, timeout=timeout
        )
        
        if res is None:
            raise Exception(f'Timeout waiting for screen {BombScreenEnum(bombScreenEnum).name}.')
        
        return res
    
    def wait_for_leave_screen(
        bombScreenEnum, time_beteween: float = 0.5, timeout: float = 60
    ):
        def check_screen():
            screen = BombScreen.get_current_screen()
            if screen == bombScreenEnum:
                return None
            else:
                return True

        return do_with_timeout(
            check_screen, time_beteween=time_beteween, timeout=timeout
        )


    def get_current_screen(time_beteween: float = 0.5, timeout: float = 20):
        targets = {
            BombScreenEnum.HOME.value: ImageBomb.TARGETS["identify_home"],
            BombScreenEnum.HEROES.value: ImageBomb.TARGETS["identify_heroes"],
            BombScreenEnum.LOGIN.value: ImageBomb.TARGETS["identify_login"],
            BombScreenEnum.TREASURE_HUNT.value: ImageBomb.TARGETS["identify_treasure_hunt"],
            BombScreenEnum.CHEST.value: ImageBomb.TARGETS["identify_hunt_chest"],
            BombScreenEnum.POPUP_ERROR.value: ImageBomb.TARGETS["popup_erro"],
            BombScreenEnum.SETTINGS.value: ImageBomb.TARGETS["identify_settings"],
        }
        max_value = 0
        img = ImageBomb.screen()
        screen_name = -1

        for name, target_img in targets.items():
            result = cv2.matchTemplate(img, target_img, cv2.TM_CCOEFF_NORMED)
            max_value_local = result.max()
            if max_value_local > max_value:
                max_value = max_value_local
                screen_name = name

        return screen_name if max_value > Config.get("threshold", "default") else -1

    def go_to_home(manager, current_screen = None):
        current_screen = BombScreen.get_current_screen() if current_screen == None else current_screen
        if current_screen == BombScreenEnum.TREASURE_HUNT.value:
            return
        elif current_screen == BombScreenEnum.TREASURE_HUNT.value:
            click_when_target_appears("button_back")
        elif current_screen == BombScreenEnum.HEROES.value:
            click_when_target_appears("buttun_x_close")
        elif current_screen == BombScreenEnum.CHEST.value:
            click_when_target_appears("buttun_x_close")
            return BombScreen.go_to_home(manager)
        else:
            Login.do_login(manager)
            return

        BombScreen.wait_for_screen(BombScreenEnum.HOME.value)

    def go_to_heroes(manager, current_screen = None):
        current_screen = BombScreen.get_current_screen() if current_screen == None else current_screen
        
        if current_screen == BombScreenEnum.HOME.value:
            click_when_target_appears("button_heroes")
            BombScreen.wait_for_screen(BombScreenEnum.HEROES.value)
            
        elif current_screen == BombScreenEnum.HEROES.value:
            return
        
        elif current_screen == BombScreenEnum.CHEST.value or current_screen == BombScreenEnum.SETTINGS.value:
            click_when_target_appears("buttun_x_close")
            BombScreen.wait_for_leave_screen(BombScreenEnum.CHEST.value)
            BombScreen.go_to_home(manager)
            return BombScreen.go_to_heroes(manager) 
        
        else:
            Login.do_login(manager)
            BombScreen.go_to_heroes(manager)

    def go_to_treasure_hunt(manager):
        if BombScreen.get_current_screen() == BombScreenEnum.TREASURE_HUNT.value:
            return
        else:
            BombScreen.go_to_home(manager)
            click_when_target_appears("identify_home")
            BombScreen.wait_for_screen(BombScreenEnum.TREASURE_HUNT.value)
            
    def go_to_chest(manager):
        if BombScreen.get_current_screen() == BombScreenEnum.CHEST.value:
            return
        else:
            BombScreen.go_to_treasure_hunt(manager)
            click_when_target_appears("button_hunt_chest")
            BombScreen.wait_for_screen(BombScreenEnum.CHEST.value)
            
    def do_print_chest(manager):
        
        if BombScreen.get_current_screen() != BombScreenEnum.TREASURE_HUNT.value:
            BombScreen.go_to_treasure_hunt(manager)
        
        click_when_target_appears("button_hunt_chest")
        BombScreen.wait_for_screen(BombScreenEnum.CHEST.value)
        image = None      
        try:
            if Config.get("screen", "print_full_screen"):
                image = ImageBomb.print_full_screen("chest", "chest_screen_for_geometry")
            else:
                image = ImageBomb.print_partial_screen("chest", "chest_screen_for_geometry")
        except Exception as e:
            dbg.console('Erro print chest Bomb', 'INFO', 'ambos', 'BOMB')
        BombScreen.go_to_treasure_hunt(manager)
        manager.set_refresh_timer("refresh_print_chest")
        


class Login:
    def do_login(manager):
        current_screen = BombScreen.get_current_screen()
        logged = False
        
        if current_screen != BombScreenEnum.HOME.value and current_screen != BombScreenEnum.NOT_FOUND.value and current_screen != BombScreenEnum.POPUP_ERROR.value:
            logged = True

        if not logged:

            login_attepmts = Config.PROPERTIES["screen"]["number_login_attempts"]
        
            for i in range(login_attepmts):
                
                if BombScreen.get_current_screen() != BombScreenEnum.HOME.value:
                    refresh_page()
                    BombScreen.wait_for_screen(BombScreenEnum.HOME.value)
                if not click_when_target_appears("button_connect_wallet"):
                    refresh_page()
                    continue                
                if not click_when_target_appears("polygon_chain"):
                    refresh_page()
                    continue
                if not click_when_target_appears("play_button"):
                    refresh_page()
                    continue
                if not click_when_target_appears("metamask_button"):
                    refresh_page()
                    continue
                if not click_when_target_appears("sign_button"):
                    refresh_page()
                    continue

                dbg.console('Login bomb OK', 'INFO', 'ambos', 'BOMB')  
                logged = True
                break

                '''if (BombScreen.wait_for_screen(BombScreenEnum.TREASURE_HUNT.value) != BombScreenEnum.TREASURE_HUNT.value):
                    continue
                else:
                    dbg.console('Login bomb OK', 'INFO', 'ambos', 'BOMB')  
                    logged = True
                    break'''

        manager.set_refresh_timer("refresh_login")
        return logged


class Hero:
    def who_needs_work(manager, num_acc):
        dbg.console('Heros to work', 'INFO', 'ambos', "BOMB:" + str(num_acc))         
        heroes_bar = [
            "hero_bar_0", "hero_bar_10", "hero_bar_20",
            "hero_bar_30", "hero_bar_40", "hero_bar_50",
            "hero_bar_60", "hero_bar_70", "hero_bar_80",
            "hero_bar_90", "hero_bar_100"
            ]
        heroes_rarity = [
            "hero_rarity_Common", "hero_rarity_Rare", "hero_rarity_SuperRare", "hero_rarity_Epic", "hero_rarity_Legend", "hero_rarity_SuperLegend"
        ]

        scale_factor = 10

        current_screen = BombScreen.get_current_screen()
        BombScreen.go_to_home(manager, current_screen)
        current_screen = BombScreenEnum.HOME.value
        BombScreen.go_to_heroes(manager, current_screen)
        
        def click_available_heroes():
            n_clicks = 0
            screen_img = ImageBomb.screen()
            
            buttons_position = ImageBomb.get_target_positions("button_work_unchecked", not_target="button_work_checked", screen_image=screen_img)            
            if not buttons_position:
                return 0

            x_buttons = buttons_position[0][0]
            height, width = ImageBomb.TARGETS["hero_search_area"].shape[:2]
            screen_img = screen_img[:,x_buttons-width-ImageBomb.MONITOR_LEFT:x_buttons - ImageBomb.MONITOR_LEFT, :]
            for button_position in buttons_position:
                x,y,w,h = button_position
                search_img = screen_img[y:y+height, :, :]

                rarity_max_values = [ImageBomb.get_compare_result(search_img, ImageBomb.TARGETS[rarity]).max() for rarity in heroes_rarity]
                rarity_index, rarity_max_value= 0, 0
                for i, value in enumerate(rarity_max_values):
                    rarity_index, rarity_max_value = (i, value) if value > rarity_max_value else (rarity_index, rarity_max_value)

                hero_rarity = heroes_rarity[rarity_index].split("_")[-1]

                life_max_values = [ImageBomb.get_compare_result(search_img, ImageBomb.TARGETS[bar]).max() for bar in heroes_bar]
                life_index, life_max_value= 0, 0
                for i, value in enumerate(life_max_values):
                    life_index, life_max_value = (i, value) if value >= life_max_value else (life_index, life_max_value)

                if life_index*scale_factor >= Config.get('heroes_work_mod', hero_rarity):
                    click_randomly_in_position(x,y,w,h)
                    n_clicks += 1

            return n_clicks

        n_clicks_per_scrool = scroll_and_click_on_targets(
            safe_scroll_target="hero_bar_vertical",
            repeat=Config.get('screen','scroll_heroes', 'repeat'),
            distance=Config.get('screen','scroll_heroes', 'distance'),
            duration=Config.get('screen','scroll_heroes', 'duration'),
            wait=Config.get('screen','scroll_heroes', 'wait'),
            function_between=click_available_heroes
        )        
        Hero.refresh_hunt(manager)
        manager.set_refresh_timer("refresh_heroes")
        return True

    def refresh_hunt(manager):
        BombScreen.go_to_home(manager)
        BombScreen.go_to_treasure_hunt(manager)
        manager.set_refresh_timer("refresh_hunt")
        return True
    
    def go_farming(manager):
        current_screen = BombScreen.get_current_screen()

        BombScreen.wait_for_screen(BombScreenEnum.TREASURE_HUNT.value)
        
        if current_screen == BombScreenEnum.TREASURE_HUNT.value:
            if not click_when_target_appears("identify_treasure_hunt"):
                pass
        return True
    
    def do_check_error(manager):        
        current_screen = BombScreen.get_current_screen()
        
        if current_screen == BombScreenEnum.POPUP_ERROR.value or current_screen == BombScreenEnum.NOT_FOUND.value:
            Login.do_login(manager)
            BombScreen.go_to_heroes(manager)
            BombScreen.go_to_treasure_hunt(manager)

        manager.set_refresh_timer("refresh_check_error")


================================================
FILE: modules/config.py
================================================
import yaml


class Config:
    PROPERTIES = {}

    @staticmethod
    def load_config(config_file):
        with open(config_file, "r") as stream:
            Config.PROPERTIES = yaml.safe_load(stream)
    
    def get(*args):
        value_to_return = Config.PROPERTIES
        for arg in args:
            value_to_return = value_to_return[arg]
        return value_to_return



================================================
FILE: modules/imageBomb.py
================================================
from os import listdir
from turtle import width
import mss
import numpy as np
from cv2 import cv2
from .config import Config
from .utils import *


class ImageBomb:
    TARGETS = []
    MONITOR_LEFT = None
    MONITOR_TOP = None

    @staticmethod
    def load_targets():
        path = "img_compare/bomberland_images/"
        file_names = listdir(path)

        targets = {}
        for file in file_names:
            targets[replace(file, ".png")] = cv2.imread(path + file)

        ImageBomb.TARGETS = targets

    def screen():
        with mss.mss() as sct:
            monitor = sct.monitors[0]
            sct_img = np.array(sct.grab(monitor))
            ImageBomb.MONITOR_LEFT = monitor["left"]
            ImageBomb.MONITOR_TOP = monitor["top"]
            return sct_img[:, :, :3]
    
    def get_monitor_with_target(target):
        position_bomb = ImageBomb.get_one_target_position(target, 0)
        with mss.mss() as sct:
            monitors = sct.monitors
        
        for monitor in monitors:
            if len(monitors) == 1:
                return monitor.values()
            if ImageBomb.position_inside_position(position_bomb, monitor.values()):
                return monitor.values()

        return monitors[0]
    
    def get_compare_result(img1, img2):
        return cv2.matchTemplate(img1, img2, cv2.TM_CCOEFF_NORMED)

    
    def position_inside_position(position_in, position_out):
        x_in,y_in,w_in,h_in = position_in
        x_out,y_out,w_out,h_out = position_out

        start_inside_x = x_out <= x_in <= (x_out+w_out)
        finish_inside_x = x_out <= x_in + w_in <= (x_out + w_out)
        start_inside_y = y_out <= y_in <= (y_out+h_out)
        finish_inside_y = y_out <= y_in + h_in <= (y_out + h_out)
        
        return start_inside_x and finish_inside_x and start_inside_y and finish_inside_y


    def print_full_screen(image_name: str, target):
        image_name = f'{image_name}.png'
        monitor_screen = ImageBomb.get_monitor_with_target(target)
        image = pyautogui.screenshot(region=(monitor_screen))
        image.save(image_name)
        return image_name
        
    def print_partial_screen(image_name: str, target: str):
        image_name = f'{image_name}.png'
        x,y,w,h = ImageBomb.get_one_target_position(target, 0)
        image = pyautogui.screenshot(region=(x,y,w,h))
        image.save(image_name)
        return image_name

    def get_target_positions(target:str, screen_image = None, threshold:float=0.8, not_target:str=None):
        threshold_config = Config.PROPERTIES["threshold"]["hero_to_work"]
        if(threshold_config):
            threshold = threshold_config
            
        target_img = ImageBomb.TARGETS[target]
        screen_img = ImageBomb.screen() if screen_image is None else screen_image
        result = cv2.matchTemplate(screen_img, target_img, cv2.TM_CCOEFF_NORMED)

        if not_target is not None:
            not_target_img = ImageBomb.TARGETS[not_target]
            not_target_result = cv2.matchTemplate(screen_img, not_target_img, cv2.TM_CCOEFF_NORMED)
            result[result < not_target_result] = 0

        y_result, x_result = np.where( result >= threshold)
        
        
        height, width = target_img.shape[:2]
        targets_positions = []
        for (x,y) in zip(x_result, y_result):
            x += ImageBomb.MONITOR_LEFT
            y += ImageBomb.MONITOR_TOP
            targets_positions.append([x,y,width,height])
            
        return targets_positions
    
    def get_one_target_position(target:str, threshold:float=0.8):
        threshold_config = Config.get("threshold", "default")
        if(threshold_config):
            threshold = threshold_config
            
        target_img = ImageBomb.TARGETS[target]
        screen_img = ImageBomb.screen()
        result = cv2.matchTemplate(screen_img, target_img, cv2.TM_CCOEFF_NORMED)

        if result.max() < threshold:
            raise Exception(f"{target} not found")
            
        yloc, xloc = np.where(result == result.max())
        xloc += ImageBomb.MONITOR_LEFT
        yloc += ImageBomb.MONITOR_TOP
        height, width = target_img.shape[:2]
        
        return xloc[0], yloc[0], width, height

    def get_max_result_between(targets:list, y_limits=None, x_limits=None, threshold:float=0):
        index = 0
        max_result = 0
        for i, target in enumerate(targets):
            screen = ImageBomb.screen()
            if y_limits is not None:
                screen= screen[y_limits[0]:y_limits[1], :]
            if x_limits is not None:
                x,w = x_limits
                screen= screen[:, x:x+w]
            result = cv2.matchTemplate(screen, ImageBomb.TARGETS[target], cv2.TM_CCOEFF_NORMED)
            if result.max() > max_result:
                max_result = result.max()
                index = i
        
        return index


    def filter_by_green_bar(item):
        x,y,w,h = item
        y_increment = round(h*0.1)
        screen_img = ImageBomb.screen()[y:y+h+y_increment,:]
        result = ImageBomb.get_target_positions("hero_bar_green", screen_image=screen_img)
        return len(result) > 0
      

================================================
FILE: modules/managerBomb.py
================================================
import time
from .bombScreen import BombScreen, BombScreenEnum, Hero, Login
from .utils import *
from .window import get_windows
from .config import Config
from debug import Debug

dbg = Debug('debug.log')

def create_bombcrypto_managers():
    return [BombcryptoManager(w) for w in get_windows('BOMB')]

class BombcryptoManager:
    def __init__(self, window) -> None:
        self.window = window
        self.refresh_login = now() + Config.get('screen', 'refresh_login')*60
        self.refresh_heroes = 0
        self.refresh_hunt = 0
        self.refresh_print_chest = 0
        self.refresh_check_error = 0

    def __enter__(self):
        self.window.activate()
        time.sleep(2)
        return self

    def __exit__(self, type, value, tb):
        return

    def do_what_needs_to_be_done(self, current_screen, num_acc):
                
        check_error = current_screen == BombScreenEnum.POPUP_ERROR.value or current_screen == BombScreenEnum.NOT_FOUND.value

        Login.do_login(self)
        
        '''refresh_check_error = Config.get('screen', 'refresh_check_error')*60
        if ((check_error) or (refresh_check_error and (now() - self.refresh_check_error > refresh_check_error))):
            Hero.do_check_error(self)'''

        refresh_login = Config.get('screen', 'refresh_login')*60
        if (refresh_login and (now() - self.refresh_login > refresh_login)):
            Login.do_login(self)

        refresh_hunt = Config.get('screen', 'refresh_hunt')*60
        if (refresh_hunt and (now() - self.refresh_hunt > refresh_hunt)):
            dbg.console('Refresh Hunt', 'INFO', 'ambos', "BOMB:" + str(num_acc))
            #Hero.refresh_hunt(self)
            Hero.go_farming(self)
            
        '''refresh_heroes=Config.get('screen', 'refresh_heroes')*60
        if (refresh_heroes and (now() - self.refresh_heroes > refresh_heroes)):
            Hero.who_needs_work(self, num_acc)'''
        return True
    
    def set_refresh_timer(self, propertie_name):
        setattr(self, propertie_name, time.time())



================================================
FILE: modules/mouseBomb.py
================================================
import time
import pyautogui
from .imageBomb import ImageBomb
from .utils import *


def click_on_multiple_targets(target: str, not_click:str= None, filter_func = None):
    targets_positions = ImageBomb.get_target_positions(target, not_target=not_click)
    n_before = (len(targets_positions))
    if filter_func is not None:
        targets_positions = filter(filter_func, targets_positions)
    click_count = 0
    for x, y, w, h in targets_positions:
        x, y, move_duration, click_duration, time_between  = randomize_values(x, w, y, h)
        pyautogui.moveTo(x, y, duration=move_duration, tween=pyautogui.easeOutQuad)
        time.sleep(time_between)
        pyautogui.click(duration=click_duration)
        click_count += 1
    
    return click_count    

def click_one_target(target: str):
    result = None
    try:
        x_left, y_top, w, h = ImageBomb.get_one_target_position(target)
        x, y, move_duration, click_duration, time_between  = randomize_values(x_left, w, y_top, h)
        pyautogui.moveTo(x, y, duration=move_duration, tween=pyautogui.easeOutQuad)
        time.sleep(time_between)
        pyautogui.click(duration=click_duration)
        result = True
    except Exception as e:
        return None
    
    return result

def click_randomly_in_position(x, y, w, h):
    x, y, move_duration, click_duration, time_between  = randomize_values(x, w, y, h)
    pyautogui.moveTo(x, y, duration=move_duration, tween=pyautogui.easeOutQuad)
    time.sleep(time_between)
    pyautogui.click(duration=click_duration)


def click_when_target_appears(target: str, time_beteween: float = 0.5, timeout: float = 10):
    return do_with_timeout(click_one_target, args = [target])


def randomize_values(x, w, y, h):
    x_rand = randomize_int(x, w, 0.20)
    y_rand = randomize_int(y, h, 0.20)
    move_duration = randomize(0.1, 0.5)
    click_duration = randomize(0.05, 0.2)
    time_between = randomize(0.05, 0.3)
    return x_rand, y_rand, move_duration, click_duration, time_between

def move_to(target:str):
    def move_to_logical():
        try:
            x, y, w, h = ImageBomb.get_one_target_position(target)
            x, y, move_duration, click_duration, time_between  = randomize_values(x, w, y, h)
            pyautogui.moveTo(x, y, duration=move_duration, tween=pyautogui.easeOutQuad)
            return True
        except Exception as e:
            return None

    return do_with_timeout(move_to_logical)

def scroll_and_click_on_targets(safe_scroll_target: str, repeat: int, distance:float, duration: float, wait:float, function_between, execute_before=True):
    res = []
    if execute_before:
        res.append(function_between())
    for i in range(repeat):
        move_to(safe_scroll_target)
        pyautogui.mouseDown(duration=0.1)
        pyautogui.moveRel(0, distance, duration)
        time.sleep(0.3)
        pyautogui.mouseUp(duration=0.1)
        time.sleep(wait)
        click_when_target_appears(safe_scroll_target)
        res.append(function_between())        
    return res

================================================
FILE: modules/platform.py
================================================
import sys
from enum import Enum

class PlatformEnum(Enum):
    LINUX = 1
    WINDOWS = 2

class Platform:
    def get_platform(self):
        is_linux = sys.platform == "linux" or sys.platform == "linux2"
        if is_linux:
            return PlatformEnum.LINUX
        else:
            return PlatformEnum.WINDOWS


================================================
FILE: modules/utils.py
================================================
import time
from random import *
import pyautogui

def date_formatted(format="%Y-%m-%d %H:%M:%S"):
    return time.strftime(format, time.localtime())

def replace(string, strReplace):
    if strReplace and string.endswith(strReplace):
        return string[: -len(strReplace)]
    return string

def randomness_number(n, randomn_factor_size=None):
    if randomn_factor_size is None:
        randomness_percentage = 0.1
        randomn_factor_size = randomness_percentage * n

    random_factor = 2 * random() * randomn_factor_size
    if random_factor > 5:
        random_factor = 5
    without_average_random_factor = n - randomn_factor_size
    randomized_n = int(without_average_random_factor + random_factor)

    return int(randomized_n)

def randomize(loc: float, width: float, safe_factor=0):
    if safe_factor > 0.5:
        raise ValueError("safe_factor must be between 0 and 0.5")
    safe_dist = width * safe_factor
    min_value = loc + safe_dist
    max_value = loc + width - safe_dist    
    return uniform(min_value, max_value)

def randomize_int(loc: float, width: float, safe_factor=0):
    return round(randomize(loc, width, safe_factor))

def refresh_page(delay:int = 5):  
    shortcut_config = 1
    if shortcut_config == 1:
        pyautogui.hotkey('ctrl', 'f5')
    else:
        with pyautogui.hold('ctrl'):
            with pyautogui.hold('shift'):
                pyautogui.press('r')
    
def do_with_timeout(function, args = [], kwargs = {}, time_beteween: float = 0.5, timeout: float = 20):
    start_time = time.time()
    while True:
        if time.time() - start_time > timeout:
            return None        
        result = function(*args, **kwargs)
        if result is not None:
            return result        
        time.sleep(time_beteween)

def now():
    return time.time()

================================================
FILE: modules/window.py
================================================
import subprocess
from modules.platform import Platform, PlatformEnum

def get_windows(type):
    return (
        _get_linux_windows(type)
        if Platform().get_platform() == PlatformEnum.LINUX
        else _get_windows(type)
    )

def _get_linux_windows(type):
    if type == 'BOMB':
        stdout = (
            subprocess.Popen(
                "xdotool search --name Bomber Land", shell=True, stdout=subprocess.PIPE
            )
            .communicate()[0]
            .decode("utf-8")
            .strip()
        )
    windows = stdout.split("\n")
    return [LinuxWindow(w) for w in windows]

def _get_windows(type):
    import pygetwindow
    if type == 'BOMB':
        return [DefaultWindow(w) for w in pygetwindow.getWindowsWithTitle("Bomber Land")]

class LinuxWindow:
    def __init__(self, window_id) -> None:
        self.window = window_id
    def activate(self):        
        subprocess.Popen(f"xdotool windowactivate {self.window}", shell=True)

class DefaultWindow:
    def __init__(self, window) -> None:
        self.window = window
    def activate(self):
        self.window.activate()


================================================
FILE: requirements.txt
================================================
MouseInfo==0.1.3
mss==6.1.0
numpy==1.21.4
opencv-python==4.5.4.60
PyAutoGUI==0.9.53
PyGetWindow==0.0.9
PyMsgBox==1.0.9
pyperclip==1.8.2
PyRect==0.1.4
PyScreeze==0.1.28
pytweening==1.0.4
PyYAML==6.0
pillow==9.0.0
Download .txt
gitextract_4c99dw9i/

├── .gitignore
├── README.md
├── bomb_settings.yaml
├── bomberland-bot.py
├── debug.py
├── modules/
│   ├── bombScreen.py
│   ├── config.py
│   ├── imageBomb.py
│   ├── managerBomb.py
│   ├── mouseBomb.py
│   ├── platform.py
│   ├── utils.py
│   └── window.py
└── requirements.txt
Download .txt
SYMBOL INDEX (70 symbols across 10 files)

FILE: bomberland-bot.py
  function main (line 43) | def main():

FILE: debug.py
  class Debug (line 6) | class Debug:
    method __init__ (line 7) | def __init__(self, filename):
    method console (line 18) | def console(self, msg, level, destino, type):

FILE: modules/bombScreen.py
  class BombScreenEnum (line 11) | class BombScreenEnum(Enum):
  class BombScreen (line 21) | class BombScreen:
    method wait_for_screen (line 22) | def wait_for_screen(
    method wait_for_leave_screen (line 40) | def wait_for_leave_screen(
    method get_current_screen (line 55) | def get_current_screen(time_beteween: float = 0.5, timeout: float = 20):
    method go_to_home (line 78) | def go_to_home(manager, current_screen = None):
    method go_to_heroes (line 95) | def go_to_heroes(manager, current_screen = None):
    method go_to_treasure_hunt (line 115) | def go_to_treasure_hunt(manager):
    method go_to_chest (line 123) | def go_to_chest(manager):
    method do_print_chest (line 131) | def do_print_chest(manager):
  class Login (line 151) | class Login:
    method do_login (line 152) | def do_login(manager):
  class Hero (line 199) | class Hero:
    method who_needs_work (line 200) | def who_needs_work(manager, num_acc):
    method refresh_hunt (line 264) | def refresh_hunt(manager):
    method go_farming (line 270) | def go_farming(manager):
    method do_check_error (line 280) | def do_check_error(manager):

FILE: modules/config.py
  class Config (line 4) | class Config:
    method load_config (line 8) | def load_config(config_file):
    method get (line 12) | def get(*args):

FILE: modules/imageBomb.py
  class ImageBomb (line 10) | class ImageBomb:
    method load_targets (line 16) | def load_targets():
    method screen (line 26) | def screen():
    method get_monitor_with_target (line 34) | def get_monitor_with_target(target):
    method get_compare_result (line 47) | def get_compare_result(img1, img2):
    method position_inside_position (line 51) | def position_inside_position(position_in, position_out):
    method print_full_screen (line 63) | def print_full_screen(image_name: str, target):
    method print_partial_screen (line 70) | def print_partial_screen(image_name: str, target: str):
    method get_target_positions (line 77) | def get_target_positions(target:str, screen_image = None, threshold:fl...
    method get_one_target_position (line 103) | def get_one_target_position(target:str, threshold:float=0.8):
    method get_max_result_between (line 122) | def get_max_result_between(targets:list, y_limits=None, x_limits=None,...
    method filter_by_green_bar (line 140) | def filter_by_green_bar(item):

FILE: modules/managerBomb.py
  function create_bombcrypto_managers (line 10) | def create_bombcrypto_managers():
  class BombcryptoManager (line 13) | class BombcryptoManager:
    method __init__ (line 14) | def __init__(self, window) -> None:
    method __enter__ (line 22) | def __enter__(self):
    method __exit__ (line 27) | def __exit__(self, type, value, tb):
    method do_what_needs_to_be_done (line 30) | def do_what_needs_to_be_done(self, current_screen, num_acc):
    method set_refresh_timer (line 55) | def set_refresh_timer(self, propertie_name):

FILE: modules/mouseBomb.py
  function click_on_multiple_targets (line 7) | def click_on_multiple_targets(target: str, not_click:str= None, filter_f...
  function click_one_target (line 22) | def click_one_target(target: str):
  function click_randomly_in_position (line 36) | def click_randomly_in_position(x, y, w, h):
  function click_when_target_appears (line 43) | def click_when_target_appears(target: str, time_beteween: float = 0.5, t...
  function randomize_values (line 47) | def randomize_values(x, w, y, h):
  function move_to (line 55) | def move_to(target:str):
  function scroll_and_click_on_targets (line 67) | def scroll_and_click_on_targets(safe_scroll_target: str, repeat: int, di...

FILE: modules/platform.py
  class PlatformEnum (line 4) | class PlatformEnum(Enum):
  class Platform (line 8) | class Platform:
    method get_platform (line 9) | def get_platform(self):

FILE: modules/utils.py
  function date_formatted (line 5) | def date_formatted(format="%Y-%m-%d %H:%M:%S"):
  function replace (line 8) | def replace(string, strReplace):
  function randomness_number (line 13) | def randomness_number(n, randomn_factor_size=None):
  function randomize (line 26) | def randomize(loc: float, width: float, safe_factor=0):
  function randomize_int (line 34) | def randomize_int(loc: float, width: float, safe_factor=0):
  function refresh_page (line 37) | def refresh_page(delay:int = 5):
  function do_with_timeout (line 46) | def do_with_timeout(function, args = [], kwargs = {}, time_beteween: flo...
  function now (line 56) | def now():

FILE: modules/window.py
  function get_windows (line 4) | def get_windows(type):
  function _get_linux_windows (line 11) | def _get_linux_windows(type):
  function _get_windows (line 24) | def _get_windows(type):
  class LinuxWindow (line 29) | class LinuxWindow:
    method __init__ (line 30) | def __init__(self, window_id) -> None:
    method activate (line 32) | def activate(self):
  class DefaultWindow (line 35) | class DefaultWindow:
    method __init__ (line 36) | def __init__(self, window) -> None:
    method activate (line 38) | def activate(self):
Condensed preview — 14 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (39K chars).
[
  {
    "path": ".gitignore",
    "chars": 203,
    "preview": "# IDE\n.vim\n\n# log\n/logs/new-map.log\n/logs/logger.log\nlogs/\n\n# cache\n/src/__pycache__\n/captcha/__pycache__\ndebug.log\nrewa"
  },
  {
    "path": "README.md",
    "chars": 3556,
    "preview": "# 🚀 Bomber Land Crypto auto click bot ready-to-use 🚀\n\n![image](https://github.com/cryptotwinsbr/bomberland-bot/assets/26"
  },
  {
    "path": "bomb_settings.yaml",
    "chars": 1912,
    "preview": "generals:\n  # Save all logs in file logs/logger.txt\n  #   0: Don't save log\n  #   1: Save log\n  save_log_file: 0\n  \n  # "
  },
  {
    "path": "bomberland-bot.py",
    "chars": 2860,
    "preview": "# -*- coding: utf-8 -*-    \nimport pyautogui\nimport sys\nimport time\nfrom debug import Debug\nimport yaml\nfrom modules.con"
  },
  {
    "path": "debug.py",
    "chars": 1726,
    "preview": "import time\nimport datetime\nimport threading\nimport logging\n\nclass Debug:\n    def __init__(self, filename):\n        self"
  },
  {
    "path": "modules/bombScreen.py",
    "chars": 11655,
    "preview": "from enum import Enum\nfrom cv2 import cv2\nfrom .config import Config\nfrom .imageBomb import ImageBomb\nfrom .mouseBomb im"
  },
  {
    "path": "modules/config.py",
    "chars": 380,
    "preview": "import yaml\n\n\nclass Config:\n    PROPERTIES = {}\n\n    @staticmethod\n    def load_config(config_file):\n        with open(c"
  },
  {
    "path": "modules/imageBomb.py",
    "chars": 5191,
    "preview": "from os import listdir\nfrom turtle import width\nimport mss\nimport numpy as np\nfrom cv2 import cv2\nfrom .config import Co"
  },
  {
    "path": "modules/managerBomb.py",
    "chars": 2054,
    "preview": "import time\nfrom .bombScreen import BombScreen, BombScreenEnum, Hero, Login\nfrom .utils import *\nfrom .window import get"
  },
  {
    "path": "modules/mouseBomb.py",
    "chars": 3038,
    "preview": "import time\nimport pyautogui\nfrom .imageBomb import ImageBomb\nfrom .utils import *\n\n\ndef click_on_multiple_targets(targe"
  },
  {
    "path": "modules/platform.py",
    "chars": 319,
    "preview": "import sys\nfrom enum import Enum\n\nclass PlatformEnum(Enum):\n    LINUX = 1\n    WINDOWS = 2\n\nclass Platform:\n    def get_p"
  },
  {
    "path": "modules/utils.py",
    "chars": 1823,
    "preview": "import time\nfrom random import *\nimport pyautogui\n\ndef date_formatted(format=\"%Y-%m-%d %H:%M:%S\"):\n    return time.strft"
  },
  {
    "path": "modules/window.py",
    "chars": 1122,
    "preview": "import subprocess\nfrom modules.platform import Platform, PlatformEnum\n\ndef get_windows(type):\n    return (\n        _get_"
  },
  {
    "path": "requirements.txt",
    "chars": 211,
    "preview": "MouseInfo==0.1.3\nmss==6.1.0\nnumpy==1.21.4\nopencv-python==4.5.4.60\nPyAutoGUI==0.9.53\nPyGetWindow==0.0.9\nPyMsgBox==1.0.9\np"
  }
]

About this extraction

This page contains the full source code of the cryptotwinsbr/spacecrypto-bot GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 14 files (35.2 KB), approximately 9.3k tokens, and a symbol index with 70 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!