How I made $20 a day with CPA + Chat Spamming (Script Included)

ErinRiptide

Junior Member
Joined
Sep 5, 2022
Messages
128
Reaction score
210
I know this is an age old method but this can still give you some money. I just stopped doing this because 20$ a day just ain't worth for me. I got the inspiration from another member who
posted the method here.

So this was just a passion project to see if this could still work in 2024 and it sure did though I would rather read book than monitor this bot which makes 20$ a day but it could maybe be of some help to someone else.

So basically you could set up an android emulator/ phone and use adb + image recognition/ coordinates to specify where exactly the bot must click. There are various untapped games with even higher potential which could make 50-100$ per day and you could easily automate everything from account creation (some games have restrictions after which you could just start spamming) to spamming the chat.


Code:
import cv2
import numpy as np
import time
import logging
import sys
import os
import subprocess
from PIL import Image

IMAGE_DIR = "C:/GameAutomation/Images/" 
CHAT_ICON_IMAGE = os.path.join(IMAGE_DIR, "chat_icon.png")
CHAT_ICON_IMAGE1 = os.path.join(IMAGE_DIR, "chat_icon1.png") 
CHAT_INPUT_IMAGE = os.path.join(IMAGE_DIR, "chat_input.png")
JOIN_BUTTON_IMAGE = os.path.join(IMAGE_DIR, "join_button.png")
CLAN_ICON_IMAGE = os.path.join(IMAGE_DIR, "clan_icon.png")
HAMBURGER_ICON_IMAGE = os.path.join(IMAGE_DIR, "hamburger_icon.png")
LEAVE_BUTTON_IMAGE = os.path.join(IMAGE_DIR, "leave_button.png")
TOURNAMENT_IMAGE = os.path.join(IMAGE_DIR, "tournament.png")
CHAT_YELLOW_IMAGE = os.path.join(IMAGE_DIR, "chat_yellow.png")
CONFIRM_LEAVE_BUTTON_IMAGE = os.path.join(IMAGE_DIR, "confirm_leave_button.png")
CANCEL_BUTTON_IMAGE = os.path.join(IMAGE_DIR, "cancel_button.png")
GO_BACK_BUTTON_IMAGE = os.path.join(IMAGE_DIR, "go_back_button.png")
TOURN_CONTINUE=os.path.join(IMAGE_DIR, "tourn_continue.png")
FILTERS=os.path.join(IMAGE_DIR, "filters.png")


CHAT_MESSAGE = "" 

LOG_DIR = "C:/GameAutomation/Logs/"
os.makedirs(LOG_DIR, exist_ok=True)
LOG_FILE = os.path.join(LOG_DIR, "automation.log")

logging.basicConfig(
    filename=LOG_FILE,
    level=logging.INFO,
    format='%(asctime)s - %(levelname)s - %(message)s',
)

# Threshold for template matching
MATCH_THRESHOLD = 0.8  # Adjust based on testing

# Delay configurations (in seconds)
UI_LOAD_DELAY = 5
CLICK_DELAY = 1
SHORT_DELAY = 0.5

current_min_trophy = 200  # Starting value for Min Trophies
current_min_medal = 50     # Starting value for Min Medals
max_min_trophy = 2000      # Maximum threshold for Min Trophies
max_min_medal = 1000       # Maximum threshold for Min Medals
increment_trophy = 5       # Increment amount for Min Trophies
increment_medal = 100      # Increment amount for Min Medals
toggle_flag = False         # True for Trophy, False for Medal

# Fixed Coordinates for Clans and Filters
FIXED_X_COORD = 464  # Adjust based on your device
FIXED_Y_SETS = [
    [375, 503, 622, 743,865, 970, 1068],
    [375, 503, 622, 743,865, 970, 1068],
    [424, 540, 660,780, 900, 1020]
]

# Coordinates for UI elements (replace these with the correct values for your app)
x_filters, y_filters = 543, 250  # Coordinates for the Filters button
x_increase_trophy_button, y_increase_trophy_button = 580, 830  # Coordinates for Increase Trophy button
x_increase_medal_button, y_increase_medal_button = 580, 700  # Coordinates for Increase Medal button
x_save_button, y_save_button = 470, 1170  # Coordinates for the Save button

# ADB Path (if not in PATH, specify full path)
ADB_PATH = 'adb'  # or 'C:/Path/To/adb.exe'

# ------------------------------ Helper Functions ------------------------------

def log_and_print(message, level="info"):
    """Logs the message and prints it to the console."""
    levels = {
        "info": logging.info,
        "warning": logging.warning,
        "error": logging.error,
        "critical": logging.critical
    }
    levels.get(level, logging.info)(message)
    print(f"[{level.upper()}] {message}")

def adb_shell(command_args):
    """Executes an adb shell command and returns the output."""
    try:
        result = subprocess.check_output([ADB_PATH, 'shell'] + command_args, stderr=subprocess.STDOUT)
        return result.decode('utf-8')
    except subprocess.CalledProcessError as e:
        log_and_print(f"ADB command failed: {e}", "error")
        return None

def adb_input_tap(x, y):
    """Performs an adb shell input tap at the specified coordinates."""
    try:
        subprocess.check_call([ADB_PATH, 'shell', 'input', 'tap', str(x), str(y)])
        log_and_print(f"ADB tap at ({x}, {y})", "info")
        time.sleep(CLICK_DELAY)
        return True
    except subprocess.CalledProcessError as e:
        log_and_print(f"ADB tap failed: {e}", "error")
        return False

def adb_screencap():
    """
    Takes a screenshot using adb exec-out and returns the image as a NumPy array.
    Streams the screenshot directly without saving it to disk.
    """
    try:
        # Execute screencap and stream the output directly
        screenshot_bytes = subprocess.check_output([ADB_PATH, 'exec-out', 'screencap', '-p'])
       
        # Convert the byte data to a NumPy array
        nparr = np.frombuffer(screenshot_bytes, np.uint8)
       
        # Decode the image from the NumPy array
        image = cv2.imdecode(nparr, cv2.IMREAD_COLOR)
       
        if image is None:
            log_and_print("Failed to decode the screenshot image.", "error")
            return None
       
        log_and_print("Screenshot captured successfully using exec-out.", "info")
        return image

    except subprocess.CalledProcessError as e:
        log_and_print(f"ADB screencap (exec-out) failed: {e}", "error")
        return None
    except Exception as e:
        log_and_print(f"Unexpected error during adb_screencap_exec_out: {e}", "error")
        return None

def get_screen_size():
    """Gets the screen size of the device."""
    output = adb_shell(['wm', 'size'])
    if output:
        size_line = output.strip()
        if 'Physical size:' in size_line:
            size_str = size_line.split('Physical size:')[1].strip()
            width, height = map(int, size_str.split('x'))
            log_and_print(f"Screen size: {width}x{height}", "info")
            return width, height
    log_and_print("Failed to get screen size.", "error")
    return None, None

def find_image_on_screen(template_path, color=None, threshold=MATCH_THRESHOLD, region=None):
    """
    Searches for the given image on the screen within the specified region.
    If a color is provided, only clicks on that color within the found image.
    Returns the top-left coordinates if found, else None.
    """
    try:
        screenshot = adb_screencap()
        if screenshot is None:
            log_and_print("Failed to capture screenshot.", "error")
            return None

        if region:
            x1, y1, x2, y2 = region
            screenshot = screenshot[y1:y2, x1:x2]

        template = cv2.imread(template_path, cv2.IMREAD_COLOR)
        if template is None:
            log_and_print(f"Template image '{template_path}' not found.", "error")
            return None

        template_gray = cv2.cvtColor(template, cv2.COLOR_BGR2GRAY)
        w, h = template_gray.shape[::-1]

        screenshot_gray = cv2.cvtColor(screenshot, cv2.COLOR_BGR2GRAY)

        # Template matching
        res = cv2.matchTemplate(screenshot_gray, template_gray, cv2.TM_CCOEFF_NORMED)
        loc = np.where(res >= threshold)

        for pt in zip(*loc[::-1]):
            # Log the match details
            log_and_print(f"Found image '{os.path.basename(template_path)}' at ({pt[0]}, {pt[1]}).", "info")

            if color:
                # Crop the found region from the screenshot
                found_region = screenshot[pt[1]:pt[1]+h, pt[0]:pt[0]+w]

                # Define the color range for detection (assuming BGR format)
                lower_color = np.array(color[0])  # Lower bound of the color
                upper_color = np.array(color[1])  # Upper bound of the color

                # Create a mask for the specified color
                mask = cv2.inRange(found_region, lower_color, upper_color)

                # Find the contours of the colored regions
                contours, _ = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

                if contours:
                    # Get the center of the largest colored area
                    largest_contour = max(contours, key=cv2.contourArea)
                    M = cv2.moments(largest_contour)
                    if M["m00"] > 0:
                        center_x = int(M["m10"] / M["m00"]) + pt[0]
                        center_y = int(M["m01"] / M["m00"]) + pt[1]

                        log_and_print(f"Found color region at ({center_x}, {center_y}).", "info")
                        return (center_x, center_y)
            else:
                return pt

        log_and_print(f"Image '{os.path.basename(template_path)}' not found on the screen.", "warning")
        return None

    except Exception as e:
        log_and_print(f"Exception in find_image_on_screen: {e}", "error")
        return None

def click_image(template_path, color=None, threshold=MATCH_THRESHOLD, region=None):
    """
    Finds the image on the screen and clicks its center using adb tap.
    If a color is provided, clicks on that color within the found image.
    Returns True if clicked, else False.
    """
    pt = find_image_on_screen(template_path, color, threshold, region)
    if pt:
        template = cv2.imread(template_path, cv2.IMREAD_COLOR)
        if template is None:
            log_and_print(f"Template image '{template_path}' not found during click.", "error")
            return False

        if not color:  # Click on the center of the image if no color is provided
            h, w, _ = template.shape
            center_x = (pt[0] + w // 2) +5
            center_y = pt[1] + h // 2
        else:
            # If color is provided, pt is already the color's center
            center_x, center_y = pt

        # Perform adb tap
        if adb_input_tap(center_x, center_y):
            log_and_print(f"Clicked on '{os.path.basename(template_path)}' at ({center_x}, {center_y}).", "info")
            return True
        else:
            return False
    return False

def tap_screen(x=None, y=None):
    """
    Taps on the screen at the specified (x, y) coordinates using adb tap.
    If no coordinates are provided, does nothing.
    """
    try:
        if x is not None and y is not None:
            if adb_input_tap(x, y):
                log_and_print(f"Tapped on the screen at ({x}, {y})", "info")
                return True
            else:
                return False
        else:
            log_and_print("No coordinates provided for tap_screen.", "error")
            return False
    except Exception as e:
        log_and_print(f"Exception during screen tap: {e}", "error")
        return False

def drag_scroll(x_start=340, y_start=1090, x_end=340, y_end=360, num_scrolls=1, duration=2000):
    try:
        log_and_print(f"Swipe coordinates from ({x_start}, {y_start}) to ({x_end}, {y_end})", "info")
       
        for i in range(num_scrolls):
            subprocess.check_call([
                ADB_PATH, 'shell', 'input', 'swipe',
                str(x_start), str(y_start), str(x_end), str(y_end), str(duration)
            ])
            log_and_print(f"Performed swipe {i+1}/{num_scrolls} from ({x_start}, {y_start}) to ({x_end}, {y_end})", "info")
            time.sleep(SHORT_DELAY)  # Delay between swipes

        log_and_print("Completed drag_scroll_fixed operation successfully.", "info")
        return True

    except subprocess.CalledProcessError as e:
        log_and_print(f"ADB swipe command failed: {e}", "error")
        return False
    except Exception as e:
        log_and_print(f"Exception during drag_scroll_fixed: {e}", "error")
        return False

def wait_for_image(template_path, timeout=15, check_interval=0.5, region=None):
    """
    Waits until the specified image appears on the screen or until timeout.
    Returns True if found, else False.
    """
    start_time = time.time()
    while time.time() - start_time < timeout:
        if find_image_on_screen(template_path, region=region):
            log_and_print(f"Image '{os.path.basename(template_path)}' found during wait.", "info")
            return True
        time.sleep(check_interval)
    log_and_print(f"Timeout reached. Image '{os.path.basename(template_path)}' not found.", "warning")
    return False

def simulate_long_press():
    """
    Simulates a long press at (200, 1200) to bring up the 'Paste' option.
    """
    try:
        # Simulate a long press at (200, 1200) for 1.5 seconds
        subprocess.check_call([ADB_PATH, 'shell', 'input', 'swipe', '200', '1200', '200', '1200', '1500'])
        log_and_print("Simulated long press at (200, 1200).", "info")
        return True
    except subprocess.CalledProcessError as e:
        log_and_print(f"Failed to simulate long press: {e}", "error")
        return False

def simulate_paste():
    """
    Simulates a tap at (75, 1230) to select the 'Paste' option.
    """
    try:
        # Simulate a tap at (75, 1230) to choose 'Paste'
        subprocess.check_call([ADB_PATH, 'shell', 'input', 'tap', '75', '1230'])
        log_and_print("Simulated tap on 'Paste' option at (75, 1230).", "info")
        return True
    except subprocess.CalledProcessError as e:
        log_and_print(f"Failed to simulate paste: {e}", "error")
        return False


def send_chat_message():
    """
    Sends a predefined chat message.
    """
    # Click on Chat Icon
    if not click_image(CHAT_ICON_IMAGE):
        log_and_print("Failed to click on Chat Icon.", "error")
        return False

    log_and_print("Clicked on Chat Icon.", "info")
    time.sleep(SHORT_DELAY)

    # Click on Chat Input Field
    if not click_image(CHAT_INPUT_IMAGE):
        log_and_print("Failed to click on Chat Input Field.", "error")
        return False

    log_and_print("Clicked on Chat Input Field.", "info")
    time.sleep(SHORT_DELAY)
    if not simulate_long_press():
        log_and_print("Failed to simulate long press for 'Paste' option.", "error")
        return False

    # Simulate Paste
    if not simulate_paste():
        log_and_print("Failed to simulate paste.", "error")
        return False
    time.sleep(SHORT_DELAY)

    if not adb_input_tap(500,500):
        return False



   
    if not click_image(CHAT_ICON_IMAGE1):
        log_and_print("Failed to click on Chat Icon to send message.", "error")
        return False


    log_and_print("Clicked on Chat Icon to send the message.", "info")

    time.sleep(CLICK_DELAY)
    return True

def leave_clan():
    """
    Leaves the currently joined clan by navigating through the UI.
    """
    # Click on Clan Icon to navigate back to clan list
    if not click_image(CLAN_ICON_IMAGE):
        log_and_print("Failed to click on Clan Icon.", "error")
        return False

    time.sleep(SHORT_DELAY)

    # Click on Hamburger Icon
    if not click_image(HAMBURGER_ICON_IMAGE):
        log_and_print("Failed to click on Hamburger Icon.", "error")
        return False

    time.sleep(SHORT_DELAY)

    # Click on Leave Button
    if not click_image(LEAVE_BUTTON_IMAGE):
        log_and_print("Failed to click on Leave Button.", "error")
        return False

    log_and_print("Clicked on Leave Button. Waiting for confirmation dialog.", "info")
    time.sleep(SHORT_DELAY)

    # Wait for the confirmation Leave Button to appear
    if CONFIRM_LEAVE_BUTTON_IMAGE and os.path.isfile(CONFIRM_LEAVE_BUTTON_IMAGE):
        if not wait_for_image(CONFIRM_LEAVE_BUTTON_IMAGE, timeout=10):
            log_and_print("Confirmation Leave Button did not appear.", "error")
            return False

        # Click on Confirm Leave Button
        if not click_image(CONFIRM_LEAVE_BUTTON_IMAGE):
            log_and_print("Failed to click on Confirm Leave Button.", "error")
            return False
    else:
        # Using the same Leave Button Image for confirmation
        if not wait_for_image(LEAVE_BUTTON_IMAGE, timeout=10):
            log_and_print("Confirmation Leave Button did not appear.", "error")
            return False

        # Click on Confirm Leave Button
        if not click_image(LEAVE_BUTTON_IMAGE):
            log_and_print("Failed to click on Confirm Leave Button.", "error")
            return False

    log_and_print("Successfully confirmed leaving the clan.", "info")
    time.sleep(UI_LOAD_DELAY)
    return True
def process_clan_at_position(x_coord, y_coord):
    """
    Processes a single clan at the given x_coord and y_coord.
    """
    try:
        log_and_print(f"Processing clan at (x={x_coord}, y={y_coord}).", "info")

        # Tap on the clan position
        if not tap_screen(x_coord, y_coord):
            log_and_print("Failed to tap on clan position.", "error")
            return False

        time.sleep(UI_LOAD_DELAY)

        # Click on Join Button
        if not click_image(JOIN_BUTTON_IMAGE):
            log_and_print("Failed to click on Join button.", "error")
            return False
       
        if not tap_screen(332, 238):
            log_and_print("Failed to tap on clan position.", "error")
            return False


        time.sleep(CLICK_DELAY)

        # Handle Cancel button if appears
        if find_image_on_screen(CANCEL_BUTTON_IMAGE):
            log_and_print("Cancel Button detected after clicking Join. Clicking Cancel.", "info")
            if not click_image(CANCEL_BUTTON_IMAGE):
                log_and_print("Failed to click on Cancel Button.", "error")
            time.sleep(SHORT_DELAY)
            # Go back to the clan list
            if not click_image(GO_BACK_BUTTON_IMAGE):
                log_and_print("Failed to click on Go Back Button.", "error")
            time.sleep(SHORT_DELAY)
            return True  # Skip further actions for this clan

        # Wait to ensure UI readiness
        time.sleep(1)
        tap_screen(500,500)
        time.sleep(5)

        if find_image_on_screen(TOURNAMENT_IMAGE, threshold=MATCH_THRESHOLD):
            if not click_image(TOURN_CONTINUE,threshold=MATCH_THRESHOLD):
                log_and_print("Failed to click on TOURN CONTINUE.", "error")
                return False
            if not click_image(TOURN_CONTINUE,threshold=MATCH_THRESHOLD):
                log_and_print("Failed to click on TOURN CONTINUE.", "error")
                return False
            time.sleep(3)
            log_and_print("Tournament detected.", "info")
            if not click_image(CHAT_YELLOW_IMAGE, threshold=0.75):
                log_and_print("Failed to click on CHAT_YELLOW_IMAGE.", "error")
                return False
            time.sleep(SHORT_DELAY)

        # Send chat message
        if not send_chat_message():
            log_and_print("Failed to send chat message.", "error")
            return False

        # Leave clan
        if not leave_clan():
            log_and_print("Failed to leave the clan.", "error")
            return False

        time.sleep(SHORT_DELAY)  # Wait between clans

        return True

    except Exception as e:
        log_and_print(f"Exception in process_clan_at_position: {e}", "error")
        return False

def send_word_by_word(chat_message):
    """
    Sends a chat message word by word with spaces in between using adb shell input.
   
    Parameters:
    - chat_message: The message string to be sent word by word.
    """
    words = chat_message.split(" ")  # Split message into words
    try:
        for word in words:
            # Send each word
            subprocess.check_call([ADB_PATH, 'shell', 'input', 'text', word])
            # Simulate space key press
            subprocess.check_call([ADB_PATH, 'shell', 'input', 'keyevent', '62'])
            time.sleep(SHORT_DELAY)  # Add delay between each word
        return True
    except subprocess.CalledProcessError as e:
        print(f"Failed to send word by word message: {e}")
        return False
def apply_filters_and_medals():
    """
    Applies filters and medals, then saves the settings.
    Alternates between increasing Min Trophies and Min Medals.
    Uses fixed x, y coordinates instead of image recognition.
    """
    global current_min_trophy, current_min_medal, toggle_flag

    # Tap on Filters button
    if not click_image(FILTERS,threshold=MATCH_THRESHOLD):
        log_and_print("Failed to tap on Filters button.", "error")
        return False

    time.sleep(SHORT_DELAY)

    # Determine which filter to adjust
    if toggle_flag:
        # Adjust Min Trophies
        log_and_print("Adjusting Minimum Trophies.", "info")
        if current_min_trophy >= max_min_trophy:
            log_and_print(f"Minimum Trophies reached max threshold ({max_min_trophy}). Skipping adjustment.", "warning")
        else:
            # Tap on Increase Trophy button
            if not tap_screen(x_increase_trophy_button, y_increase_trophy_button):
                log_and_print("Failed to tap on Increase Trophy button.", "error")
                return False

            # Update the current_min_trophy
            current_min_trophy += increment_trophy
            log_and_print(f"Increased Minimum Trophies to {current_min_trophy}.", "info")
    else:
        # Adjust Min Medals
        log_and_print("Adjusting Minimum Medals.", "info")
        if current_min_medal >= max_min_medal:
            log_and_print(f"Minimum Medals reached max threshold ({max_min_medal}). Skipping adjustment.", "warning")
        else:
            # Tap on Increase Medal button
            if not tap_screen(x_increase_medal_button, y_increase_medal_button):
                log_and_print("Failed to tap on Increase Medal button.", "error")
                return False

            # Update the current_min_medal
            current_min_medal += increment_medal
            log_and_print(f"Increased Minimum Medals to {current_min_medal}.", "info")

    # Toggle for next adjustment
    toggle_flag = not toggle_flag

    time.sleep(SHORT_DELAY)

    # Tap on Save button
    if not tap_screen(x_save_button, y_save_button):
        log_and_print("Failed to tap on Save button.", "error")
        return False

    log_and_print("Filters and Medals applied and saved successfully.", "info")
    time.sleep(UI_LOAD_DELAY)
    return True

# ------------------------------ Main Automation Function ------------------------------

def automate_game_operations():
    """
    Automates processing of clans using fixed coordinates and performs drag scrolls based on the index.
    Implements a retry mechanism for processing clans.
    """
    log_and_print("Automation script started.", "info")

    # Verify that all required images exist
    required_images = [
        CHAT_ICON_IMAGE,
        CHAT_INPUT_IMAGE,
        JOIN_BUTTON_IMAGE,
        CLAN_ICON_IMAGE,
        HAMBURGER_ICON_IMAGE,
        LEAVE_BUTTON_IMAGE,
        CONFIRM_LEAVE_BUTTON_IMAGE,
        CHAT_ICON_IMAGE1,
        CANCEL_BUTTON_IMAGE,
        # Add any additional required images here
    ]
    all_exist = True
    for img in required_images:
        if not os.path.isfile(img):
            log_and_print(f"Required image '{img}' is missing.", "critical")
            all_exist = False
    if not all_exist:
        log_and_print("One or more required images are missing. Exiting.", "critical")
        sys.exit(1)

    # Initialize variables
    clan_index = -1  # To keep track of the overall clan index

    # Define retry parameters
    MAX_RETRIES = 2       # Maximum number of retries per clan
    RETRY_DELAY = 3       # Delay between retries in seconds

    while True:
        # Iterate through each set of Y coordinates
        for index, y_set in enumerate(FIXED_Y_SETS):
            for y_coord in y_set:
                clan_index += 1  # Increment clan index at the start
                retry_count = 0   # Initialize retry count for the current clan

                while retry_count <= MAX_RETRIES:
                    log_and_print(f"Processing clan #{clan_index} at (x={FIXED_X_COORD}, y={y_coord}). Attempt {retry_count + 1}/{MAX_RETRIES}.", "info")
                    success = process_clan_at_position(FIXED_X_COORD, y_coord)

                    if success:
                        log_and_print(f"Successfully processed clan #{clan_index}.", "info")
                        break  # Exit the retry loop and proceed to the next clan
                    else:
                        retry_count += 1
                        if retry_count < MAX_RETRIES:
                            log_and_print(f"Retrying clan #{clan_index} after {RETRY_DELAY} seconds...", "warning")
                            time.sleep(RETRY_DELAY)
                        else:
                            log_and_print(f"Failed to process clan #{clan_index} after {MAX_RETRIES} attempts. Skipping to the next clan.", "error")
               
                # Scroll based on the current clan index
                if 6 <= clan_index < 13:  # For clans 7 to 14 (index 6 to 13)
                    log_and_print(f"Scrolling once after processing clan #{clan_index}.", "info")
                    drag_scroll()
                elif clan_index >= 13:  # For clans 15 and onwards
                    log_and_print(f"Scrolling twice after processing clan #{clan_index}.", "info")
                    drag_scroll()
                    drag_scroll()

        # Apply filters and medals after processing all clan sets
        apply_filters_and_medals()
        log_and_print("Applying filters and medals after processing all clan sets.", "info")

        # Reset clan index for the next iteration
        clan_index = 0

        # Check for a stopping condition if necessary
        # For demonstration, we'll break after one full iteration
        # Remove or modify this condition as needed
        log_and_print("Completed one full iteration. Exiting loop.", "info")
       

    log_and_print("Automation script completed.", "info")

# ------------------------------ Initial Filters Application ------------------------------

def apply_initial_filters_and_medals():
    log_and_print("Applying initial filters and medals.", "info")

# ------------------------------ Main Entry Point ------------------------------

def main():
    try:
        apply_initial_filters_and_medals()
        automate_game_operations()
    except KeyboardInterrupt:
        log_and_print("Script interrupted by user.", "warning")
    except Exception as e:
        log_and_print(f"Unexpected exception: {e}", "critical")
        sys.exit(1)

if __name__ == "__main__":
    main()
    sys.exit(0)

Earnings Proof:
1731404637424.png
 
Which category of games?
Its like spamming on games chat rooms right?
 
Okay but it will going to restrict account or ban from chatrooms right?
You gotta have scripts to create accounts if that happens. Like 2 different bots 1 for account creation and leveling up. 1 for spamming. TBH i've not done this.

But there are games which take a while to ban you say 4-10 hrs and you could easily make like 20 bucks in that timeframe. 1 game I saw required to complete a tutorial for 5 mins and then allowed you to participate in the global chat and in 3 hours I made like 10$. So you could just make a bot to complete tutorial and a seperate bot to spam.

I would say you gotta checkout different games and first try spamming manually before building a bot for the same.
 
hi bro plz can u give me exemple of chat rom to know what do you mean ? and how i can find it chat rom of any game
 
hi bro plz can u give me exemple of chat rom to know what do you mean ? and how i can find it chat rom of any game
Find other games like clash of clans, rush royale etc less popular games like these.
 
Great tip brother! Awesome idea.
do you have a more recent method?
 
Find other games like clash of clans, rush royale etc less popular games like these.
yiu don't understand my question , i mean can you give me exemple of any games chat rom like what'a the chat rom of clach of clans or monopoly go ? did you mean discord, facebook group chat rom ? plz specifie the chat rom meaning budy
 
I know this is an age old method but this can still give you some money. I just stopped doing this because 20$ a day just ain't worth for me. I got the inspiration from another member who
posted the method here.

So this was just a passion project to see if this could still work in 2024 and it sure did though I would rather read book than monitor this bot which makes 20$ a day but it could maybe be of some help to someone else.

So basically you could set up an android emulator/ phone and use adb + image recognition/ coordinates to specify where exactly the bot must click. There are various untapped games with even higher potential which could make 50-100$ per day and you could easily automate everything from account creation (some games have restrictions after which you could just start spamming) to spamming the chat.


Code:
import cv2
import numpy as np
import time
import logging
import sys
import os
import subprocess
from PIL import Image

IMAGE_DIR = "C:/GameAutomation/Images/"
CHAT_ICON_IMAGE = os.path.join(IMAGE_DIR, "chat_icon.png")
CHAT_ICON_IMAGE1 = os.path.join(IMAGE_DIR, "chat_icon1.png")
CHAT_INPUT_IMAGE = os.path.join(IMAGE_DIR, "chat_input.png")
JOIN_BUTTON_IMAGE = os.path.join(IMAGE_DIR, "join_button.png")
CLAN_ICON_IMAGE = os.path.join(IMAGE_DIR, "clan_icon.png")
HAMBURGER_ICON_IMAGE = os.path.join(IMAGE_DIR, "hamburger_icon.png")
LEAVE_BUTTON_IMAGE = os.path.join(IMAGE_DIR, "leave_button.png")
TOURNAMENT_IMAGE = os.path.join(IMAGE_DIR, "tournament.png")
CHAT_YELLOW_IMAGE = os.path.join(IMAGE_DIR, "chat_yellow.png")
CONFIRM_LEAVE_BUTTON_IMAGE = os.path.join(IMAGE_DIR, "confirm_leave_button.png")
CANCEL_BUTTON_IMAGE = os.path.join(IMAGE_DIR, "cancel_button.png")
GO_BACK_BUTTON_IMAGE = os.path.join(IMAGE_DIR, "go_back_button.png")
TOURN_CONTINUE=os.path.join(IMAGE_DIR, "tourn_continue.png")
FILTERS=os.path.join(IMAGE_DIR, "filters.png")


CHAT_MESSAGE = ""

LOG_DIR = "C:/GameAutomation/Logs/"
os.makedirs(LOG_DIR, exist_ok=True)
LOG_FILE = os.path.join(LOG_DIR, "automation.log")

logging.basicConfig(
    filename=LOG_FILE,
    level=logging.INFO,
    format='%(asctime)s - %(levelname)s - %(message)s',
)

# Threshold for template matching
MATCH_THRESHOLD = 0.8  # Adjust based on testing

# Delay configurations (in seconds)
UI_LOAD_DELAY = 5
CLICK_DELAY = 1
SHORT_DELAY = 0.5

current_min_trophy = 200  # Starting value for Min Trophies
current_min_medal = 50     # Starting value for Min Medals
max_min_trophy = 2000      # Maximum threshold for Min Trophies
max_min_medal = 1000       # Maximum threshold for Min Medals
increment_trophy = 5       # Increment amount for Min Trophies
increment_medal = 100      # Increment amount for Min Medals
toggle_flag = False         # True for Trophy, False for Medal

# Fixed Coordinates for Clans and Filters
FIXED_X_COORD = 464  # Adjust based on your device
FIXED_Y_SETS = [
    [375, 503, 622, 743,865, 970, 1068],
    [375, 503, 622, 743,865, 970, 1068],
    [424, 540, 660,780, 900, 1020]
]

# Coordinates for UI elements (replace these with the correct values for your app)
x_filters, y_filters = 543, 250  # Coordinates for the Filters button
x_increase_trophy_button, y_increase_trophy_button = 580, 830  # Coordinates for Increase Trophy button
x_increase_medal_button, y_increase_medal_button = 580, 700  # Coordinates for Increase Medal button
x_save_button, y_save_button = 470, 1170  # Coordinates for the Save button

# ADB Path (if not in PATH, specify full path)
ADB_PATH = 'adb'  # or 'C:/Path/To/adb.exe'

# ------------------------------ Helper Functions ------------------------------

def log_and_print(message, level="info"):
    """Logs the message and prints it to the console."""
    levels = {
        "info": logging.info,
        "warning": logging.warning,
        "error": logging.error,
        "critical": logging.critical
    }
    levels.get(level, logging.info)(message)
    print(f"[{level.upper()}] {message}")

def adb_shell(command_args):
    """Executes an adb shell command and returns the output."""
    try:
        result = subprocess.check_output([ADB_PATH, 'shell'] + command_args, stderr=subprocess.STDOUT)
        return result.decode('utf-8')
    except subprocess.CalledProcessError as e:
        log_and_print(f"ADB command failed: {e}", "error")
        return None

def adb_input_tap(x, y):
    """Performs an adb shell input tap at the specified coordinates."""
    try:
        subprocess.check_call([ADB_PATH, 'shell', 'input', 'tap', str(x), str(y)])
        log_and_print(f"ADB tap at ({x}, {y})", "info")
        time.sleep(CLICK_DELAY)
        return True
    except subprocess.CalledProcessError as e:
        log_and_print(f"ADB tap failed: {e}", "error")
        return False

def adb_screencap():
    """
    Takes a screenshot using adb exec-out and returns the image as a NumPy array.
    Streams the screenshot directly without saving it to disk.
    """
    try:
        # Execute screencap and stream the output directly
        screenshot_bytes = subprocess.check_output([ADB_PATH, 'exec-out', 'screencap', '-p'])
      
        # Convert the byte data to a NumPy array
        nparr = np.frombuffer(screenshot_bytes, np.uint8)
      
        # Decode the image from the NumPy array
        image = cv2.imdecode(nparr, cv2.IMREAD_COLOR)
      
        if image is None:
            log_and_print("Failed to decode the screenshot image.", "error")
            return None
      
        log_and_print("Screenshot captured successfully using exec-out.", "info")
        return image

    except subprocess.CalledProcessError as e:
        log_and_print(f"ADB screencap (exec-out) failed: {e}", "error")
        return None
    except Exception as e:
        log_and_print(f"Unexpected error during adb_screencap_exec_out: {e}", "error")
        return None

def get_screen_size():
    """Gets the screen size of the device."""
    output = adb_shell(['wm', 'size'])
    if output:
        size_line = output.strip()
        if 'Physical size:' in size_line:
            size_str = size_line.split('Physical size:')[1].strip()
            width, height = map(int, size_str.split('x'))
            log_and_print(f"Screen size: {width}x{height}", "info")
            return width, height
    log_and_print("Failed to get screen size.", "error")
    return None, None

def find_image_on_screen(template_path, color=None, threshold=MATCH_THRESHOLD, region=None):
    """
    Searches for the given image on the screen within the specified region.
    If a color is provided, only clicks on that color within the found image.
    Returns the top-left coordinates if found, else None.
    """
    try:
        screenshot = adb_screencap()
        if screenshot is None:
            log_and_print("Failed to capture screenshot.", "error")
            return None

        if region:
            x1, y1, x2, y2 = region
            screenshot = screenshot[y1:y2, x1:x2]

        template = cv2.imread(template_path, cv2.IMREAD_COLOR)
        if template is None:
            log_and_print(f"Template image '{template_path}' not found.", "error")
            return None

        template_gray = cv2.cvtColor(template, cv2.COLOR_BGR2GRAY)
        w, h = template_gray.shape[::-1]

        screenshot_gray = cv2.cvtColor(screenshot, cv2.COLOR_BGR2GRAY)

        # Template matching
        res = cv2.matchTemplate(screenshot_gray, template_gray, cv2.TM_CCOEFF_NORMED)
        loc = np.where(res >= threshold)

        for pt in zip(*loc[::-1]):
            # Log the match details
            log_and_print(f"Found image '{os.path.basename(template_path)}' at ({pt[0]}, {pt[1]}).", "info")

            if color:
                # Crop the found region from the screenshot
                found_region = screenshot[pt[1]:pt[1]+h, pt[0]:pt[0]+w]

                # Define the color range for detection (assuming BGR format)
                lower_color = np.array(color[0])  # Lower bound of the color
                upper_color = np.array(color[1])  # Upper bound of the color

                # Create a mask for the specified color
                mask = cv2.inRange(found_region, lower_color, upper_color)

                # Find the contours of the colored regions
                contours, _ = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

                if contours:
                    # Get the center of the largest colored area
                    largest_contour = max(contours, key=cv2.contourArea)
                    M = cv2.moments(largest_contour)
                    if M["m00"] > 0:
                        center_x = int(M["m10"] / M["m00"]) + pt[0]
                        center_y = int(M["m01"] / M["m00"]) + pt[1]

                        log_and_print(f"Found color region at ({center_x}, {center_y}).", "info")
                        return (center_x, center_y)
            else:
                return pt

        log_and_print(f"Image '{os.path.basename(template_path)}' not found on the screen.", "warning")
        return None

    except Exception as e:
        log_and_print(f"Exception in find_image_on_screen: {e}", "error")
        return None

def click_image(template_path, color=None, threshold=MATCH_THRESHOLD, region=None):
    """
    Finds the image on the screen and clicks its center using adb tap.
    If a color is provided, clicks on that color within the found image.
    Returns True if clicked, else False.
    """
    pt = find_image_on_screen(template_path, color, threshold, region)
    if pt:
        template = cv2.imread(template_path, cv2.IMREAD_COLOR)
        if template is None:
            log_and_print(f"Template image '{template_path}' not found during click.", "error")
            return False

        if not color:  # Click on the center of the image if no color is provided
            h, w, _ = template.shape
            center_x = (pt[0] + w // 2) +5
            center_y = pt[1] + h // 2
        else:
            # If color is provided, pt is already the color's center
            center_x, center_y = pt

        # Perform adb tap
        if adb_input_tap(center_x, center_y):
            log_and_print(f"Clicked on '{os.path.basename(template_path)}' at ({center_x}, {center_y}).", "info")
            return True
        else:
            return False
    return False

def tap_screen(x=None, y=None):
    """
    Taps on the screen at the specified (x, y) coordinates using adb tap.
    If no coordinates are provided, does nothing.
    """
    try:
        if x is not None and y is not None:
            if adb_input_tap(x, y):
                log_and_print(f"Tapped on the screen at ({x}, {y})", "info")
                return True
            else:
                return False
        else:
            log_and_print("No coordinates provided for tap_screen.", "error")
            return False
    except Exception as e:
        log_and_print(f"Exception during screen tap: {e}", "error")
        return False

def drag_scroll(x_start=340, y_start=1090, x_end=340, y_end=360, num_scrolls=1, duration=2000):
    try:
        log_and_print(f"Swipe coordinates from ({x_start}, {y_start}) to ({x_end}, {y_end})", "info")
      
        for i in range(num_scrolls):
            subprocess.check_call([
                ADB_PATH, 'shell', 'input', 'swipe',
                str(x_start), str(y_start), str(x_end), str(y_end), str(duration)
            ])
            log_and_print(f"Performed swipe {i+1}/{num_scrolls} from ({x_start}, {y_start}) to ({x_end}, {y_end})", "info")
            time.sleep(SHORT_DELAY)  # Delay between swipes

        log_and_print("Completed drag_scroll_fixed operation successfully.", "info")
        return True

    except subprocess.CalledProcessError as e:
        log_and_print(f"ADB swipe command failed: {e}", "error")
        return False
    except Exception as e:
        log_and_print(f"Exception during drag_scroll_fixed: {e}", "error")
        return False

def wait_for_image(template_path, timeout=15, check_interval=0.5, region=None):
    """
    Waits until the specified image appears on the screen or until timeout.
    Returns True if found, else False.
    """
    start_time = time.time()
    while time.time() - start_time < timeout:
        if find_image_on_screen(template_path, region=region):
            log_and_print(f"Image '{os.path.basename(template_path)}' found during wait.", "info")
            return True
        time.sleep(check_interval)
    log_and_print(f"Timeout reached. Image '{os.path.basename(template_path)}' not found.", "warning")
    return False

def simulate_long_press():
    """
    Simulates a long press at (200, 1200) to bring up the 'Paste' option.
    """
    try:
        # Simulate a long press at (200, 1200) for 1.5 seconds
        subprocess.check_call([ADB_PATH, 'shell', 'input', 'swipe', '200', '1200', '200', '1200', '1500'])
        log_and_print("Simulated long press at (200, 1200).", "info")
        return True
    except subprocess.CalledProcessError as e:
        log_and_print(f"Failed to simulate long press: {e}", "error")
        return False

def simulate_paste():
    """
    Simulates a tap at (75, 1230) to select the 'Paste' option.
    """
    try:
        # Simulate a tap at (75, 1230) to choose 'Paste'
        subprocess.check_call([ADB_PATH, 'shell', 'input', 'tap', '75', '1230'])
        log_and_print("Simulated tap on 'Paste' option at (75, 1230).", "info")
        return True
    except subprocess.CalledProcessError as e:
        log_and_print(f"Failed to simulate paste: {e}", "error")
        return False


def send_chat_message():
    """
    Sends a predefined chat message.
    """
    # Click on Chat Icon
    if not click_image(CHAT_ICON_IMAGE):
        log_and_print("Failed to click on Chat Icon.", "error")
        return False

    log_and_print("Clicked on Chat Icon.", "info")
    time.sleep(SHORT_DELAY)

    # Click on Chat Input Field
    if not click_image(CHAT_INPUT_IMAGE):
        log_and_print("Failed to click on Chat Input Field.", "error")
        return False

    log_and_print("Clicked on Chat Input Field.", "info")
    time.sleep(SHORT_DELAY)
    if not simulate_long_press():
        log_and_print("Failed to simulate long press for 'Paste' option.", "error")
        return False

    # Simulate Paste
    if not simulate_paste():
        log_and_print("Failed to simulate paste.", "error")
        return False
    time.sleep(SHORT_DELAY)

    if not adb_input_tap(500,500):
        return False



  
    if not click_image(CHAT_ICON_IMAGE1):
        log_and_print("Failed to click on Chat Icon to send message.", "error")
        return False


    log_and_print("Clicked on Chat Icon to send the message.", "info")

    time.sleep(CLICK_DELAY)
    return True

def leave_clan():
    """
    Leaves the currently joined clan by navigating through the UI.
    """
    # Click on Clan Icon to navigate back to clan list
    if not click_image(CLAN_ICON_IMAGE):
        log_and_print("Failed to click on Clan Icon.", "error")
        return False

    time.sleep(SHORT_DELAY)

    # Click on Hamburger Icon
    if not click_image(HAMBURGER_ICON_IMAGE):
        log_and_print("Failed to click on Hamburger Icon.", "error")
        return False

    time.sleep(SHORT_DELAY)

    # Click on Leave Button
    if not click_image(LEAVE_BUTTON_IMAGE):
        log_and_print("Failed to click on Leave Button.", "error")
        return False

    log_and_print("Clicked on Leave Button. Waiting for confirmation dialog.", "info")
    time.sleep(SHORT_DELAY)

    # Wait for the confirmation Leave Button to appear
    if CONFIRM_LEAVE_BUTTON_IMAGE and os.path.isfile(CONFIRM_LEAVE_BUTTON_IMAGE):
        if not wait_for_image(CONFIRM_LEAVE_BUTTON_IMAGE, timeout=10):
            log_and_print("Confirmation Leave Button did not appear.", "error")
            return False

        # Click on Confirm Leave Button
        if not click_image(CONFIRM_LEAVE_BUTTON_IMAGE):
            log_and_print("Failed to click on Confirm Leave Button.", "error")
            return False
    else:
        # Using the same Leave Button Image for confirmation
        if not wait_for_image(LEAVE_BUTTON_IMAGE, timeout=10):
            log_and_print("Confirmation Leave Button did not appear.", "error")
            return False

        # Click on Confirm Leave Button
        if not click_image(LEAVE_BUTTON_IMAGE):
            log_and_print("Failed to click on Confirm Leave Button.", "error")
            return False

    log_and_print("Successfully confirmed leaving the clan.", "info")
    time.sleep(UI_LOAD_DELAY)
    return True
def process_clan_at_position(x_coord, y_coord):
    """
    Processes a single clan at the given x_coord and y_coord.
    """
    try:
        log_and_print(f"Processing clan at (x={x_coord}, y={y_coord}).", "info")

        # Tap on the clan position
        if not tap_screen(x_coord, y_coord):
            log_and_print("Failed to tap on clan position.", "error")
            return False

        time.sleep(UI_LOAD_DELAY)

        # Click on Join Button
        if not click_image(JOIN_BUTTON_IMAGE):
            log_and_print("Failed to click on Join button.", "error")
            return False
      
        if not tap_screen(332, 238):
            log_and_print("Failed to tap on clan position.", "error")
            return False


        time.sleep(CLICK_DELAY)

        # Handle Cancel button if appears
        if find_image_on_screen(CANCEL_BUTTON_IMAGE):
            log_and_print("Cancel Button detected after clicking Join. Clicking Cancel.", "info")
            if not click_image(CANCEL_BUTTON_IMAGE):
                log_and_print("Failed to click on Cancel Button.", "error")
            time.sleep(SHORT_DELAY)
            # Go back to the clan list
            if not click_image(GO_BACK_BUTTON_IMAGE):
                log_and_print("Failed to click on Go Back Button.", "error")
            time.sleep(SHORT_DELAY)
            return True  # Skip further actions for this clan

        # Wait to ensure UI readiness
        time.sleep(1)
        tap_screen(500,500)
        time.sleep(5)

        if find_image_on_screen(TOURNAMENT_IMAGE, threshold=MATCH_THRESHOLD):
            if not click_image(TOURN_CONTINUE,threshold=MATCH_THRESHOLD):
                log_and_print("Failed to click on TOURN CONTINUE.", "error")
                return False
            if not click_image(TOURN_CONTINUE,threshold=MATCH_THRESHOLD):
                log_and_print("Failed to click on TOURN CONTINUE.", "error")
                return False
            time.sleep(3)
            log_and_print("Tournament detected.", "info")
            if not click_image(CHAT_YELLOW_IMAGE, threshold=0.75):
                log_and_print("Failed to click on CHAT_YELLOW_IMAGE.", "error")
                return False
            time.sleep(SHORT_DELAY)

        # Send chat message
        if not send_chat_message():
            log_and_print("Failed to send chat message.", "error")
            return False

        # Leave clan
        if not leave_clan():
            log_and_print("Failed to leave the clan.", "error")
            return False

        time.sleep(SHORT_DELAY)  # Wait between clans

        return True

    except Exception as e:
        log_and_print(f"Exception in process_clan_at_position: {e}", "error")
        return False

def send_word_by_word(chat_message):
    """
    Sends a chat message word by word with spaces in between using adb shell input.
  
    Parameters:
    - chat_message: The message string to be sent word by word.
    """
    words = chat_message.split(" ")  # Split message into words
    try:
        for word in words:
            # Send each word
            subprocess.check_call([ADB_PATH, 'shell', 'input', 'text', word])
            # Simulate space key press
            subprocess.check_call([ADB_PATH, 'shell', 'input', 'keyevent', '62'])
            time.sleep(SHORT_DELAY)  # Add delay between each word
        return True
    except subprocess.CalledProcessError as e:
        print(f"Failed to send word by word message: {e}")
        return False
def apply_filters_and_medals():
    """
    Applies filters and medals, then saves the settings.
    Alternates between increasing Min Trophies and Min Medals.
    Uses fixed x, y coordinates instead of image recognition.
    """
    global current_min_trophy, current_min_medal, toggle_flag

    # Tap on Filters button
    if not click_image(FILTERS,threshold=MATCH_THRESHOLD):
        log_and_print("Failed to tap on Filters button.", "error")
        return False

    time.sleep(SHORT_DELAY)

    # Determine which filter to adjust
    if toggle_flag:
        # Adjust Min Trophies
        log_and_print("Adjusting Minimum Trophies.", "info")
        if current_min_trophy >= max_min_trophy:
            log_and_print(f"Minimum Trophies reached max threshold ({max_min_trophy}). Skipping adjustment.", "warning")
        else:
            # Tap on Increase Trophy button
            if not tap_screen(x_increase_trophy_button, y_increase_trophy_button):
                log_and_print("Failed to tap on Increase Trophy button.", "error")
                return False

            # Update the current_min_trophy
            current_min_trophy += increment_trophy
            log_and_print(f"Increased Minimum Trophies to {current_min_trophy}.", "info")
    else:
        # Adjust Min Medals
        log_and_print("Adjusting Minimum Medals.", "info")
        if current_min_medal >= max_min_medal:
            log_and_print(f"Minimum Medals reached max threshold ({max_min_medal}). Skipping adjustment.", "warning")
        else:
            # Tap on Increase Medal button
            if not tap_screen(x_increase_medal_button, y_increase_medal_button):
                log_and_print("Failed to tap on Increase Medal button.", "error")
                return False

            # Update the current_min_medal
            current_min_medal += increment_medal
            log_and_print(f"Increased Minimum Medals to {current_min_medal}.", "info")

    # Toggle for next adjustment
    toggle_flag = not toggle_flag

    time.sleep(SHORT_DELAY)

    # Tap on Save button
    if not tap_screen(x_save_button, y_save_button):
        log_and_print("Failed to tap on Save button.", "error")
        return False

    log_and_print("Filters and Medals applied and saved successfully.", "info")
    time.sleep(UI_LOAD_DELAY)
    return True

# ------------------------------ Main Automation Function ------------------------------

def automate_game_operations():
    """
    Automates processing of clans using fixed coordinates and performs drag scrolls based on the index.
    Implements a retry mechanism for processing clans.
    """
    log_and_print("Automation script started.", "info")

    # Verify that all required images exist
    required_images = [
        CHAT_ICON_IMAGE,
        CHAT_INPUT_IMAGE,
        JOIN_BUTTON_IMAGE,
        CLAN_ICON_IMAGE,
        HAMBURGER_ICON_IMAGE,
        LEAVE_BUTTON_IMAGE,
        CONFIRM_LEAVE_BUTTON_IMAGE,
        CHAT_ICON_IMAGE1,
        CANCEL_BUTTON_IMAGE,
        # Add any additional required images here
    ]
    all_exist = True
    for img in required_images:
        if not os.path.isfile(img):
            log_and_print(f"Required image '{img}' is missing.", "critical")
            all_exist = False
    if not all_exist:
        log_and_print("One or more required images are missing. Exiting.", "critical")
        sys.exit(1)

    # Initialize variables
    clan_index = -1  # To keep track of the overall clan index

    # Define retry parameters
    MAX_RETRIES = 2       # Maximum number of retries per clan
    RETRY_DELAY = 3       # Delay between retries in seconds

    while True:
        # Iterate through each set of Y coordinates
        for index, y_set in enumerate(FIXED_Y_SETS):
            for y_coord in y_set:
                clan_index += 1  # Increment clan index at the start
                retry_count = 0   # Initialize retry count for the current clan

                while retry_count <= MAX_RETRIES:
                    log_and_print(f"Processing clan #{clan_index} at (x={FIXED_X_COORD}, y={y_coord}). Attempt {retry_count + 1}/{MAX_RETRIES}.", "info")
                    success = process_clan_at_position(FIXED_X_COORD, y_coord)

                    if success:
                        log_and_print(f"Successfully processed clan #{clan_index}.", "info")
                        break  # Exit the retry loop and proceed to the next clan
                    else:
                        retry_count += 1
                        if retry_count < MAX_RETRIES:
                            log_and_print(f"Retrying clan #{clan_index} after {RETRY_DELAY} seconds...", "warning")
                            time.sleep(RETRY_DELAY)
                        else:
                            log_and_print(f"Failed to process clan #{clan_index} after {MAX_RETRIES} attempts. Skipping to the next clan.", "error")
              
                # Scroll based on the current clan index
                if 6 <= clan_index < 13:  # For clans 7 to 14 (index 6 to 13)
                    log_and_print(f"Scrolling once after processing clan #{clan_index}.", "info")
                    drag_scroll()
                elif clan_index >= 13:  # For clans 15 and onwards
                    log_and_print(f"Scrolling twice after processing clan #{clan_index}.", "info")
                    drag_scroll()
                    drag_scroll()

        # Apply filters and medals after processing all clan sets
        apply_filters_and_medals()
        log_and_print("Applying filters and medals after processing all clan sets.", "info")

        # Reset clan index for the next iteration
        clan_index = 0

        # Check for a stopping condition if necessary
        # For demonstration, we'll break after one full iteration
        # Remove or modify this condition as needed
        log_and_print("Completed one full iteration. Exiting loop.", "info")
      

    log_and_print("Automation script completed.", "info")

# ------------------------------ Initial Filters Application ------------------------------

def apply_initial_filters_and_medals():
    log_and_print("Applying initial filters and medals.", "info")

# ------------------------------ Main Entry Point ------------------------------

def main():
    try:
        apply_initial_filters_and_medals()
        automate_game_operations()
    except KeyboardInterrupt:
        log_and_print("Script interrupted by user.", "warning")
    except Exception as e:
        log_and_print(f"Unexpected exception: {e}", "critical")
        sys.exit(1)

if __name__ == "__main__":
    main()
    sys.exit(0)

Earnings Proof:
View attachment 393134
What is the code for?
 
I know this is an age old method but this can still give you some money. I just stopped doing this because 20$ a day just ain't worth for me. I got the inspiration from another member who
posted the method here.

So this was just a passion project to see if this could still work in 2024 and it sure did though I would rather read book than monitor this bot which makes 20$ a day but it could maybe be of some help to someone else.

So basically you could set up an android emulator/ phone and use adb + image recognition/ coordinates to specify where exactly the bot must click. There are various untapped games with even higher potential which could make 50-100$ per day and you could easily automate everything from account creation (some games have restrictions after which you could just start spamming) to spamming the chat.


Code:
import cv2
import numpy as np
import time
import logging
import sys
import os
import subprocess
from PIL import Image

IMAGE_DIR = "C:/GameAutomation/Images/"
CHAT_ICON_IMAGE = os.path.join(IMAGE_DIR, "chat_icon.png")
CHAT_ICON_IMAGE1 = os.path.join(IMAGE_DIR, "chat_icon1.png")
CHAT_INPUT_IMAGE = os.path.join(IMAGE_DIR, "chat_input.png")
JOIN_BUTTON_IMAGE = os.path.join(IMAGE_DIR, "join_button.png")
CLAN_ICON_IMAGE = os.path.join(IMAGE_DIR, "clan_icon.png")
HAMBURGER_ICON_IMAGE = os.path.join(IMAGE_DIR, "hamburger_icon.png")
LEAVE_BUTTON_IMAGE = os.path.join(IMAGE_DIR, "leave_button.png")
TOURNAMENT_IMAGE = os.path.join(IMAGE_DIR, "tournament.png")
CHAT_YELLOW_IMAGE = os.path.join(IMAGE_DIR, "chat_yellow.png")
CONFIRM_LEAVE_BUTTON_IMAGE = os.path.join(IMAGE_DIR, "confirm_leave_button.png")
CANCEL_BUTTON_IMAGE = os.path.join(IMAGE_DIR, "cancel_button.png")
GO_BACK_BUTTON_IMAGE = os.path.join(IMAGE_DIR, "go_back_button.png")
TOURN_CONTINUE=os.path.join(IMAGE_DIR, "tourn_continue.png")
FILTERS=os.path.join(IMAGE_DIR, "filters.png")


CHAT_MESSAGE = ""

LOG_DIR = "C:/GameAutomation/Logs/"
os.makedirs(LOG_DIR, exist_ok=True)
LOG_FILE = os.path.join(LOG_DIR, "automation.log")

logging.basicConfig(
    filename=LOG_FILE,
    level=logging.INFO,
    format='%(asctime)s - %(levelname)s - %(message)s',
)

# Threshold for template matching
MATCH_THRESHOLD = 0.8  # Adjust based on testing

# Delay configurations (in seconds)
UI_LOAD_DELAY = 5
CLICK_DELAY = 1
SHORT_DELAY = 0.5

current_min_trophy = 200  # Starting value for Min Trophies
current_min_medal = 50     # Starting value for Min Medals
max_min_trophy = 2000      # Maximum threshold for Min Trophies
max_min_medal = 1000       # Maximum threshold for Min Medals
increment_trophy = 5       # Increment amount for Min Trophies
increment_medal = 100      # Increment amount for Min Medals
toggle_flag = False         # True for Trophy, False for Medal

# Fixed Coordinates for Clans and Filters
FIXED_X_COORD = 464  # Adjust based on your device
FIXED_Y_SETS = [
    [375, 503, 622, 743,865, 970, 1068],
    [375, 503, 622, 743,865, 970, 1068],
    [424, 540, 660,780, 900, 1020]
]

# Coordinates for UI elements (replace these with the correct values for your app)
x_filters, y_filters = 543, 250  # Coordinates for the Filters button
x_increase_trophy_button, y_increase_trophy_button = 580, 830  # Coordinates for Increase Trophy button
x_increase_medal_button, y_increase_medal_button = 580, 700  # Coordinates for Increase Medal button
x_save_button, y_save_button = 470, 1170  # Coordinates for the Save button

# ADB Path (if not in PATH, specify full path)
ADB_PATH = 'adb'  # or 'C:/Path/To/adb.exe'

# ------------------------------ Helper Functions ------------------------------

def log_and_print(message, level="info"):
    """Logs the message and prints it to the console."""
    levels = {
        "info": logging.info,
        "warning": logging.warning,
        "error": logging.error,
        "critical": logging.critical
    }
    levels.get(level, logging.info)(message)
    print(f"[{level.upper()}] {message}")

def adb_shell(command_args):
    """Executes an adb shell command and returns the output."""
    try:
        result = subprocess.check_output([ADB_PATH, 'shell'] + command_args, stderr=subprocess.STDOUT)
        return result.decode('utf-8')
    except subprocess.CalledProcessError as e:
        log_and_print(f"ADB command failed: {e}", "error")
        return None

def adb_input_tap(x, y):
    """Performs an adb shell input tap at the specified coordinates."""
    try:
        subprocess.check_call([ADB_PATH, 'shell', 'input', 'tap', str(x), str(y)])
        log_and_print(f"ADB tap at ({x}, {y})", "info")
        time.sleep(CLICK_DELAY)
        return True
    except subprocess.CalledProcessError as e:
        log_and_print(f"ADB tap failed: {e}", "error")
        return False

def adb_screencap():
    """
    Takes a screenshot using adb exec-out and returns the image as a NumPy array.
    Streams the screenshot directly without saving it to disk.
    """
    try:
        # Execute screencap and stream the output directly
        screenshot_bytes = subprocess.check_output([ADB_PATH, 'exec-out', 'screencap', '-p'])
      
        # Convert the byte data to a NumPy array
        nparr = np.frombuffer(screenshot_bytes, np.uint8)
      
        # Decode the image from the NumPy array
        image = cv2.imdecode(nparr, cv2.IMREAD_COLOR)
      
        if image is None:
            log_and_print("Failed to decode the screenshot image.", "error")
            return None
      
        log_and_print("Screenshot captured successfully using exec-out.", "info")
        return image

    except subprocess.CalledProcessError as e:
        log_and_print(f"ADB screencap (exec-out) failed: {e}", "error")
        return None
    except Exception as e:
        log_and_print(f"Unexpected error during adb_screencap_exec_out: {e}", "error")
        return None

def get_screen_size():
    """Gets the screen size of the device."""
    output = adb_shell(['wm', 'size'])
    if output:
        size_line = output.strip()
        if 'Physical size:' in size_line:
            size_str = size_line.split('Physical size:')[1].strip()
            width, height = map(int, size_str.split('x'))
            log_and_print(f"Screen size: {width}x{height}", "info")
            return width, height
    log_and_print("Failed to get screen size.", "error")
    return None, None

def find_image_on_screen(template_path, color=None, threshold=MATCH_THRESHOLD, region=None):
    """
    Searches for the given image on the screen within the specified region.
    If a color is provided, only clicks on that color within the found image.
    Returns the top-left coordinates if found, else None.
    """
    try:
        screenshot = adb_screencap()
        if screenshot is None:
            log_and_print("Failed to capture screenshot.", "error")
            return None

        if region:
            x1, y1, x2, y2 = region
            screenshot = screenshot[y1:y2, x1:x2]

        template = cv2.imread(template_path, cv2.IMREAD_COLOR)
        if template is None:
            log_and_print(f"Template image '{template_path}' not found.", "error")
            return None

        template_gray = cv2.cvtColor(template, cv2.COLOR_BGR2GRAY)
        w, h = template_gray.shape[::-1]

        screenshot_gray = cv2.cvtColor(screenshot, cv2.COLOR_BGR2GRAY)

        # Template matching
        res = cv2.matchTemplate(screenshot_gray, template_gray, cv2.TM_CCOEFF_NORMED)
        loc = np.where(res >= threshold)

        for pt in zip(*loc[::-1]):
            # Log the match details
            log_and_print(f"Found image '{os.path.basename(template_path)}' at ({pt[0]}, {pt[1]}).", "info")

            if color:
                # Crop the found region from the screenshot
                found_region = screenshot[pt[1]:pt[1]+h, pt[0]:pt[0]+w]

                # Define the color range for detection (assuming BGR format)
                lower_color = np.array(color[0])  # Lower bound of the color
                upper_color = np.array(color[1])  # Upper bound of the color

                # Create a mask for the specified color
                mask = cv2.inRange(found_region, lower_color, upper_color)

                # Find the contours of the colored regions
                contours, _ = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

                if contours:
                    # Get the center of the largest colored area
                    largest_contour = max(contours, key=cv2.contourArea)
                    M = cv2.moments(largest_contour)
                    if M["m00"] > 0:
                        center_x = int(M["m10"] / M["m00"]) + pt[0]
                        center_y = int(M["m01"] / M["m00"]) + pt[1]

                        log_and_print(f"Found color region at ({center_x}, {center_y}).", "info")
                        return (center_x, center_y)
            else:
                return pt

        log_and_print(f"Image '{os.path.basename(template_path)}' not found on the screen.", "warning")
        return None

    except Exception as e:
        log_and_print(f"Exception in find_image_on_screen: {e}", "error")
        return None

def click_image(template_path, color=None, threshold=MATCH_THRESHOLD, region=None):
    """
    Finds the image on the screen and clicks its center using adb tap.
    If a color is provided, clicks on that color within the found image.
    Returns True if clicked, else False.
    """
    pt = find_image_on_screen(template_path, color, threshold, region)
    if pt:
        template = cv2.imread(template_path, cv2.IMREAD_COLOR)
        if template is None:
            log_and_print(f"Template image '{template_path}' not found during click.", "error")
            return False

        if not color:  # Click on the center of the image if no color is provided
            h, w, _ = template.shape
            center_x = (pt[0] + w // 2) +5
            center_y = pt[1] + h // 2
        else:
            # If color is provided, pt is already the color's center
            center_x, center_y = pt

        # Perform adb tap
        if adb_input_tap(center_x, center_y):
            log_and_print(f"Clicked on '{os.path.basename(template_path)}' at ({center_x}, {center_y}).", "info")
            return True
        else:
            return False
    return False

def tap_screen(x=None, y=None):
    """
    Taps on the screen at the specified (x, y) coordinates using adb tap.
    If no coordinates are provided, does nothing.
    """
    try:
        if x is not None and y is not None:
            if adb_input_tap(x, y):
                log_and_print(f"Tapped on the screen at ({x}, {y})", "info")
                return True
            else:
                return False
        else:
            log_and_print("No coordinates provided for tap_screen.", "error")
            return False
    except Exception as e:
        log_and_print(f"Exception during screen tap: {e}", "error")
        return False

def drag_scroll(x_start=340, y_start=1090, x_end=340, y_end=360, num_scrolls=1, duration=2000):
    try:
        log_and_print(f"Swipe coordinates from ({x_start}, {y_start}) to ({x_end}, {y_end})", "info")
      
        for i in range(num_scrolls):
            subprocess.check_call([
                ADB_PATH, 'shell', 'input', 'swipe',
                str(x_start), str(y_start), str(x_end), str(y_end), str(duration)
            ])
            log_and_print(f"Performed swipe {i+1}/{num_scrolls} from ({x_start}, {y_start}) to ({x_end}, {y_end})", "info")
            time.sleep(SHORT_DELAY)  # Delay between swipes

        log_and_print("Completed drag_scroll_fixed operation successfully.", "info")
        return True

    except subprocess.CalledProcessError as e:
        log_and_print(f"ADB swipe command failed: {e}", "error")
        return False
    except Exception as e:
        log_and_print(f"Exception during drag_scroll_fixed: {e}", "error")
        return False

def wait_for_image(template_path, timeout=15, check_interval=0.5, region=None):
    """
    Waits until the specified image appears on the screen or until timeout.
    Returns True if found, else False.
    """
    start_time = time.time()
    while time.time() - start_time < timeout:
        if find_image_on_screen(template_path, region=region):
            log_and_print(f"Image '{os.path.basename(template_path)}' found during wait.", "info")
            return True
        time.sleep(check_interval)
    log_and_print(f"Timeout reached. Image '{os.path.basename(template_path)}' not found.", "warning")
    return False

def simulate_long_press():
    """
    Simulates a long press at (200, 1200) to bring up the 'Paste' option.
    """
    try:
        # Simulate a long press at (200, 1200) for 1.5 seconds
        subprocess.check_call([ADB_PATH, 'shell', 'input', 'swipe', '200', '1200', '200', '1200', '1500'])
        log_and_print("Simulated long press at (200, 1200).", "info")
        return True
    except subprocess.CalledProcessError as e:
        log_and_print(f"Failed to simulate long press: {e}", "error")
        return False

def simulate_paste():
    """
    Simulates a tap at (75, 1230) to select the 'Paste' option.
    """
    try:
        # Simulate a tap at (75, 1230) to choose 'Paste'
        subprocess.check_call([ADB_PATH, 'shell', 'input', 'tap', '75', '1230'])
        log_and_print("Simulated tap on 'Paste' option at (75, 1230).", "info")
        return True
    except subprocess.CalledProcessError as e:
        log_and_print(f"Failed to simulate paste: {e}", "error")
        return False


def send_chat_message():
    """
    Sends a predefined chat message.
    """
    # Click on Chat Icon
    if not click_image(CHAT_ICON_IMAGE):
        log_and_print("Failed to click on Chat Icon.", "error")
        return False

    log_and_print("Clicked on Chat Icon.", "info")
    time.sleep(SHORT_DELAY)

    # Click on Chat Input Field
    if not click_image(CHAT_INPUT_IMAGE):
        log_and_print("Failed to click on Chat Input Field.", "error")
        return False

    log_and_print("Clicked on Chat Input Field.", "info")
    time.sleep(SHORT_DELAY)
    if not simulate_long_press():
        log_and_print("Failed to simulate long press for 'Paste' option.", "error")
        return False

    # Simulate Paste
    if not simulate_paste():
        log_and_print("Failed to simulate paste.", "error")
        return False
    time.sleep(SHORT_DELAY)

    if not adb_input_tap(500,500):
        return False



  
    if not click_image(CHAT_ICON_IMAGE1):
        log_and_print("Failed to click on Chat Icon to send message.", "error")
        return False


    log_and_print("Clicked on Chat Icon to send the message.", "info")

    time.sleep(CLICK_DELAY)
    return True

def leave_clan():
    """
    Leaves the currently joined clan by navigating through the UI.
    """
    # Click on Clan Icon to navigate back to clan list
    if not click_image(CLAN_ICON_IMAGE):
        log_and_print("Failed to click on Clan Icon.", "error")
        return False

    time.sleep(SHORT_DELAY)

    # Click on Hamburger Icon
    if not click_image(HAMBURGER_ICON_IMAGE):
        log_and_print("Failed to click on Hamburger Icon.", "error")
        return False

    time.sleep(SHORT_DELAY)

    # Click on Leave Button
    if not click_image(LEAVE_BUTTON_IMAGE):
        log_and_print("Failed to click on Leave Button.", "error")
        return False

    log_and_print("Clicked on Leave Button. Waiting for confirmation dialog.", "info")
    time.sleep(SHORT_DELAY)

    # Wait for the confirmation Leave Button to appear
    if CONFIRM_LEAVE_BUTTON_IMAGE and os.path.isfile(CONFIRM_LEAVE_BUTTON_IMAGE):
        if not wait_for_image(CONFIRM_LEAVE_BUTTON_IMAGE, timeout=10):
            log_and_print("Confirmation Leave Button did not appear.", "error")
            return False

        # Click on Confirm Leave Button
        if not click_image(CONFIRM_LEAVE_BUTTON_IMAGE):
            log_and_print("Failed to click on Confirm Leave Button.", "error")
            return False
    else:
        # Using the same Leave Button Image for confirmation
        if not wait_for_image(LEAVE_BUTTON_IMAGE, timeout=10):
            log_and_print("Confirmation Leave Button did not appear.", "error")
            return False

        # Click on Confirm Leave Button
        if not click_image(LEAVE_BUTTON_IMAGE):
            log_and_print("Failed to click on Confirm Leave Button.", "error")
            return False

    log_and_print("Successfully confirmed leaving the clan.", "info")
    time.sleep(UI_LOAD_DELAY)
    return True
def process_clan_at_position(x_coord, y_coord):
    """
    Processes a single clan at the given x_coord and y_coord.
    """
    try:
        log_and_print(f"Processing clan at (x={x_coord}, y={y_coord}).", "info")

        # Tap on the clan position
        if not tap_screen(x_coord, y_coord):
            log_and_print("Failed to tap on clan position.", "error")
            return False

        time.sleep(UI_LOAD_DELAY)

        # Click on Join Button
        if not click_image(JOIN_BUTTON_IMAGE):
            log_and_print("Failed to click on Join button.", "error")
            return False
      
        if not tap_screen(332, 238):
            log_and_print("Failed to tap on clan position.", "error")
            return False


        time.sleep(CLICK_DELAY)

        # Handle Cancel button if appears
        if find_image_on_screen(CANCEL_BUTTON_IMAGE):
            log_and_print("Cancel Button detected after clicking Join. Clicking Cancel.", "info")
            if not click_image(CANCEL_BUTTON_IMAGE):
                log_and_print("Failed to click on Cancel Button.", "error")
            time.sleep(SHORT_DELAY)
            # Go back to the clan list
            if not click_image(GO_BACK_BUTTON_IMAGE):
                log_and_print("Failed to click on Go Back Button.", "error")
            time.sleep(SHORT_DELAY)
            return True  # Skip further actions for this clan

        # Wait to ensure UI readiness
        time.sleep(1)
        tap_screen(500,500)
        time.sleep(5)

        if find_image_on_screen(TOURNAMENT_IMAGE, threshold=MATCH_THRESHOLD):
            if not click_image(TOURN_CONTINUE,threshold=MATCH_THRESHOLD):
                log_and_print("Failed to click on TOURN CONTINUE.", "error")
                return False
            if not click_image(TOURN_CONTINUE,threshold=MATCH_THRESHOLD):
                log_and_print("Failed to click on TOURN CONTINUE.", "error")
                return False
            time.sleep(3)
            log_and_print("Tournament detected.", "info")
            if not click_image(CHAT_YELLOW_IMAGE, threshold=0.75):
                log_and_print("Failed to click on CHAT_YELLOW_IMAGE.", "error")
                return False
            time.sleep(SHORT_DELAY)

        # Send chat message
        if not send_chat_message():
            log_and_print("Failed to send chat message.", "error")
            return False

        # Leave clan
        if not leave_clan():
            log_and_print("Failed to leave the clan.", "error")
            return False

        time.sleep(SHORT_DELAY)  # Wait between clans

        return True

    except Exception as e:
        log_and_print(f"Exception in process_clan_at_position: {e}", "error")
        return False

def send_word_by_word(chat_message):
    """
    Sends a chat message word by word with spaces in between using adb shell input.
  
    Parameters:
    - chat_message: The message string to be sent word by word.
    """
    words = chat_message.split(" ")  # Split message into words
    try:
        for word in words:
            # Send each word
            subprocess.check_call([ADB_PATH, 'shell', 'input', 'text', word])
            # Simulate space key press
            subprocess.check_call([ADB_PATH, 'shell', 'input', 'keyevent', '62'])
            time.sleep(SHORT_DELAY)  # Add delay between each word
        return True
    except subprocess.CalledProcessError as e:
        print(f"Failed to send word by word message: {e}")
        return False
def apply_filters_and_medals():
    """
    Applies filters and medals, then saves the settings.
    Alternates between increasing Min Trophies and Min Medals.
    Uses fixed x, y coordinates instead of image recognition.
    """
    global current_min_trophy, current_min_medal, toggle_flag

    # Tap on Filters button
    if not click_image(FILTERS,threshold=MATCH_THRESHOLD):
        log_and_print("Failed to tap on Filters button.", "error")
        return False

    time.sleep(SHORT_DELAY)

    # Determine which filter to adjust
    if toggle_flag:
        # Adjust Min Trophies
        log_and_print("Adjusting Minimum Trophies.", "info")
        if current_min_trophy >= max_min_trophy:
            log_and_print(f"Minimum Trophies reached max threshold ({max_min_trophy}). Skipping adjustment.", "warning")
        else:
            # Tap on Increase Trophy button
            if not tap_screen(x_increase_trophy_button, y_increase_trophy_button):
                log_and_print("Failed to tap on Increase Trophy button.", "error")
                return False

            # Update the current_min_trophy
            current_min_trophy += increment_trophy
            log_and_print(f"Increased Minimum Trophies to {current_min_trophy}.", "info")
    else:
        # Adjust Min Medals
        log_and_print("Adjusting Minimum Medals.", "info")
        if current_min_medal >= max_min_medal:
            log_and_print(f"Minimum Medals reached max threshold ({max_min_medal}). Skipping adjustment.", "warning")
        else:
            # Tap on Increase Medal button
            if not tap_screen(x_increase_medal_button, y_increase_medal_button):
                log_and_print("Failed to tap on Increase Medal button.", "error")
                return False

            # Update the current_min_medal
            current_min_medal += increment_medal
            log_and_print(f"Increased Minimum Medals to {current_min_medal}.", "info")

    # Toggle for next adjustment
    toggle_flag = not toggle_flag

    time.sleep(SHORT_DELAY)

    # Tap on Save button
    if not tap_screen(x_save_button, y_save_button):
        log_and_print("Failed to tap on Save button.", "error")
        return False

    log_and_print("Filters and Medals applied and saved successfully.", "info")
    time.sleep(UI_LOAD_DELAY)
    return True

# ------------------------------ Main Automation Function ------------------------------

def automate_game_operations():
    """
    Automates processing of clans using fixed coordinates and performs drag scrolls based on the index.
    Implements a retry mechanism for processing clans.
    """
    log_and_print("Automation script started.", "info")

    # Verify that all required images exist
    required_images = [
        CHAT_ICON_IMAGE,
        CHAT_INPUT_IMAGE,
        JOIN_BUTTON_IMAGE,
        CLAN_ICON_IMAGE,
        HAMBURGER_ICON_IMAGE,
        LEAVE_BUTTON_IMAGE,
        CONFIRM_LEAVE_BUTTON_IMAGE,
        CHAT_ICON_IMAGE1,
        CANCEL_BUTTON_IMAGE,
        # Add any additional required images here
    ]
    all_exist = True
    for img in required_images:
        if not os.path.isfile(img):
            log_and_print(f"Required image '{img}' is missing.", "critical")
            all_exist = False
    if not all_exist:
        log_and_print("One or more required images are missing. Exiting.", "critical")
        sys.exit(1)

    # Initialize variables
    clan_index = -1  # To keep track of the overall clan index

    # Define retry parameters
    MAX_RETRIES = 2       # Maximum number of retries per clan
    RETRY_DELAY = 3       # Delay between retries in seconds

    while True:
        # Iterate through each set of Y coordinates
        for index, y_set in enumerate(FIXED_Y_SETS):
            for y_coord in y_set:
                clan_index += 1  # Increment clan index at the start
                retry_count = 0   # Initialize retry count for the current clan

                while retry_count <= MAX_RETRIES:
                    log_and_print(f"Processing clan #{clan_index} at (x={FIXED_X_COORD}, y={y_coord}). Attempt {retry_count + 1}/{MAX_RETRIES}.", "info")
                    success = process_clan_at_position(FIXED_X_COORD, y_coord)

                    if success:
                        log_and_print(f"Successfully processed clan #{clan_index}.", "info")
                        break  # Exit the retry loop and proceed to the next clan
                    else:
                        retry_count += 1
                        if retry_count < MAX_RETRIES:
                            log_and_print(f"Retrying clan #{clan_index} after {RETRY_DELAY} seconds...", "warning")
                            time.sleep(RETRY_DELAY)
                        else:
                            log_and_print(f"Failed to process clan #{clan_index} after {MAX_RETRIES} attempts. Skipping to the next clan.", "error")
              
                # Scroll based on the current clan index
                if 6 <= clan_index < 13:  # For clans 7 to 14 (index 6 to 13)
                    log_and_print(f"Scrolling once after processing clan #{clan_index}.", "info")
                    drag_scroll()
                elif clan_index >= 13:  # For clans 15 and onwards
                    log_and_print(f"Scrolling twice after processing clan #{clan_index}.", "info")
                    drag_scroll()
                    drag_scroll()

        # Apply filters and medals after processing all clan sets
        apply_filters_and_medals()
        log_and_print("Applying filters and medals after processing all clan sets.", "info")

        # Reset clan index for the next iteration
        clan_index = 0

        # Check for a stopping condition if necessary
        # For demonstration, we'll break after one full iteration
        # Remove or modify this condition as needed
        log_and_print("Completed one full iteration. Exiting loop.", "info")
      

    log_and_print("Automation script completed.", "info")

# ------------------------------ Initial Filters Application ------------------------------

def apply_initial_filters_and_medals():
    log_and_print("Applying initial filters and medals.", "info")

# ------------------------------ Main Entry Point ------------------------------

def main():
    try:
        apply_initial_filters_and_medals()
        automate_game_operations()
    except KeyboardInterrupt:
        log_and_print("Script interrupted by user.", "warning")
    except Exception as e:
        log_and_print(f"Unexpected exception: {e}", "critical")
        sys.exit(1)

if __name__ == "__main__":
    main()
    sys.exit(0)

Earnings Proof:
View attachment 393134
hello sir
Can you please explain in detail how to add my own content locker
 
Back
Top