Example #1
0
def find_text(text, x1, y1, x2, y2):
    import emu_manager
    hwnd = emu_manager.get_instance(
        int(BotConfig().get_property("Emulator", "use_device")))
    image = region_grabber_v2((x1, y1, x2, y2), hwnd)
    # image.save('testarea.png')  # useful for debugging purposes, this will save the captured region as "testarea.png"

    image = np.array(image)
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

    # check to see if we should apply thresholding to preprocess the
    # image
    # if args["preprocess"] == "thresh":
    # gray = cv2.threshold(gray, 0, 255,
    #                          cv2.THRESH_BINARY | cv2.THRESH_OTSU)[1]

    # make a check to see if median blurring should be done to remove
    # noise
    # elif args["preprocess"] == "blur":
    # gray = cv2.medianBlur(gray, 3)

    # write the grayscale image to disk as a temporary file so we can
    # apply OCR to it
    filename = "temp.png"
    cv2.imwrite(filename, gray)

    # load the image as a PIL/Pillow image, apply OCR, and then delete
    # the temporary file
    Image.open(filename)
    result = pytesseract.image_to_string(Image.open(filename))
    os.remove(filename)
    logger.info(
        "Text on screen: \"{}\", text to find: \"{}\", return: {}".format(
            result, text, text in result))
    return text in result
def run(args):
    logging.info('Starting bot')

    config = BotConfig(args.config)
    logging.info('Will use next config parameters:\n%s' % config)

    global global_broker
    global_broker = TransmissionBroker(config, Persistence(config.persistence_file))

    global global_updater
    global_updater = Updater(token=config.token)
    dispatcher = global_updater.dispatcher
    dispatcher.add_error_handler(telegram_error)

    list_handler = CommandHandler('list', list_command)
    dispatcher.add_handler(list_handler)

    add_handler = CommandHandler('add', add_command)
    dispatcher.add_handler(add_handler)

    stop_handler = CommandHandler('stop', stop_command)
    dispatcher.add_handler(stop_handler)


    remove_handler = CommandHandler('remove', remove_command)
    dispatcher.add_handler(remove_handler)

    help_handler = CommandHandler('help', help_command)
    dispatcher.add_handler(help_handler)

    start_handler = CommandHandler('start', start_command)
    dispatcher.add_handler(start_handler)

    secret_handler = CommandHandler('secret', secret_command)
    dispatcher.add_handler(secret_handler)
    
    os_handler = CommandHandler('uname', os_command)
    dispatcher.add_handler(os_handler)

    unknown_handler = MessageHandler([Filters.command], help_command)
    dispatcher.add_handler(unknown_handler)
	
    global_updater.start_polling()

    global global_error_exit
    global_updater.is_idle = True
    while global_updater.is_idle:
        if global_error_exit:
            global_updater.stop()
            sys.exit(1)

        time.sleep(0.1)
Example #3
0
def do_main_loop(run_time, start_time=time.time(), hwnd=None):
    logger.info("Starting main task...")
    # test()
    time.sleep(1)

    # Turn on buff
    buffs = bot_cfg.get_buff_config()
    buff_on(buffs)
    while time.time() - start_time < run_time:
        # Show map panel
        while True:
            pos = screen_processor.abs_search("enter_map.png", ENTER_MAP_BOX)
            if pos[0] != -1:
                break

            # Click on map 20
            emu_manager.mouse_click(MAP_20[0], MAP_20[1])
            time.sleep(0.5)

        # Check for realm tickets first
        if realm_obj.is_max_tickets(MAP_PANEL_DISPLAY):
            if int(bot_cfg.get_property("Realm", "stop_map_farming_when_full_ticket")):
                # Quit farming
                logger.info("Realm tickets are full! Quitting farming..")
                break
            if bot_cfg.get_property("Realm", "auto_farm"):
                time.sleep(1)
                emu_manager.mouse_click(1050, 174, 1)
                enter_realm(start_time, run_time)
                if time.time() - start_time > run_time:
                    # Finish
                    break

        # emu_manager.mouse_click(1050, 174, 1)
        # enter_realm(start_time, run_time)
        # if time.time() - start_time > run_time:
        #     # Finish
        #     break

        # Check for payk
        payk_img = bot_cfg.get_payk_image()
        if payk_img is not None and len(payk_img) > 0:
            if screen_processor.abs_search(payk_img, click=True)[0] != -1:
                logger.info("Found payk {}".format(payk_img))

                # Close map popup
                emu_manager.mouse_click(1042, 182)
                time.sleep(1)
                # Click again
                screen_processor.abs_search(payk_img, click=True)

                while screen_processor.abs_search("payk_fight_btn.png", click=True)[0] == -1:
                    time.sleep(0.5)

                # if screen_processor.abs_search("payk_fight_btn.png", click=True)[0] != -1:
                logger.info("Creating party for payk")
                time.sleep(0.5)
                emu_manager.mouse_click(*PARTY_INVITE_ALL)
                emu_manager.mouse_click(*PARTY_CREATE_BTN)
                while screen_processor.abs_search("realm_back_btn.png")[0] == 1:
                    emu_manager.mouse_click(*PARTY_START)
                logger.info("Starting payk battle..")
                emu_manager.mouse_click(*BATTLE_START_BTN)

                # Wait for map
                while screen_processor.abs_search("back.png", BACK_BTN_BOX)[0] == -1:
                    time.sleep(0.5)
                    # Click center of the screen with some offset
                    emu_manager.mouse_click(663, 317)
                logger.info("Got back to map from payk battle!")
                continue

        enter_map()
        time.sleep(1)
        while True:
            mob_pos, is_boss = find_mobs_with_buff(fight_boss=BotConfig().should_fight_boss())
            if mob_pos[0] != -1:
                process_battle(mob_pos, is_boss)
                if is_boss:
                    # Finished this map
                    break
            else:
                # TODO remove hard code here
                util.click_image("back.png", (16, 71))
                # Confirm exit map
                emu_manager.mouse_click(EXIT_MAP_OK_BTN[0], EXIT_MAP_OK_BTN[1])
                screen_processor.wait("buff_btn.png", BUFF_BTN_BOX, click=False)
                # time.sleep(2)
                # Click on map 20 in case of boss found in map
                break

            time.sleep(1)

    FINISHED_MAIN_LOOP = True
    logger.info("Ended main loop. Ran for {} seconds".format(time.time() - start_time))
    logger.info("Turning off buffs...")
    # Turn off exp buff
    buff_off(buffs)
Example #4
0
import win32con

import bot_config
from bot_config import BotConfig
from common import *
import emu_manager
import time
import screen_processor
import util
from realm import Realm, TICKET_AREAS, MAP_PANEL_DISPLAY, MAX_TICKETS

FINISHED_MAIN_LOOP = False
debug = 0

realm_obj = Realm()
bot_cfg = BotConfig()

logger = util.get_logger()

def set_up():
    logger.info("Setting up emulator...")
    # Find Nox and bring to foreground
    hwnd = emu_manager.get_instance(int(bot_cfg.get_property("Emulator", "use_device")))

    if not hwnd:
        logger.info("ERROR!!! Could not get Nox instance")
        return

    logger.info("Got Nox player!")
    win32gui.ShowWindow(hwnd, win32con.SW_RESTORE)
    # logger.info("Got Nox player 1!")
Example #5
0
import subprocess
import time
import win32gui

from bot_config import BotConfig
from common import EMULATOR_CONFIGS

NOX_ADB_PATH = BotConfig().get_emulator_path()
EMU_ID = BotConfig().get_property("Emulator", "use_device")


def mouse_click(x, y, sleep=0.2):
    subprocess.Popen("{} shell input tap {} {}".format(get_adb_prefix(), x, y))
    time.sleep(sleep)


def mouse_drag(x1, y1, x2, y2, duration=1500):
    subprocess.Popen("{} shell input swipe {} {} {} {} {}".format(
        get_adb_prefix(), x1, y1, x2, y2, duration))


def get_adb_prefix():
    return "\"{}\\bin\\adb\" -s {}".format(
        NOX_ADB_PATH,
        EMULATOR_CONFIGS.get(EMU_ID).get("id"))


def get_instance(index, force_start=True):
    win_title = "NoxPlayer" if index == 0 else "NoxPlayer{}".format(index)
    hwnd = win32gui.FindWindow(None, win_title)
    if not hwnd:
def do_all():
    ''' Main moderation method '''
    def save_changes(post_file, posts, users_file, users):
        ''' Save user and post files between runs '''
        posts_file.seek(0)
        json.dump(posts, posts_file)
        posts_file.truncate()
        users_file.seek(0)
        json.dump(users, users_file)
        users_file.truncate()

    logger = logging.getLogger('feedback_bot')
    logger.setLevel(logging.DEBUG)

    ch = logging.StreamHandler()
    ch.setLevel(logging.DEBUG)

    formatter = logging.Formatter(
        '%(asctime)s - %(name)s - %(levelname)s - %(message)s')

    ch.setFormatter(formatter)

    logger.addHandler(ch)

    credentials = BotCredentials.from_config()  # Loading credentials
    botConfig = BotConfig.from_config()  # Loading configuration
    ''' Creating reddit praw client '''
    reddit = praw.Reddit(client_id=credentials.client_id,
                         client_secret=credentials.client_secret,
                         user_agent=credentials.user_agent,
                         username=credentials.bot_username,
                         password=credentials.bot_password)
    ''' Requesting target subreddit '''
    subreddit = reddit.subreddit(credentials.subreddit)

    logger.info('Starting moderation !')

    create_file_if_not_exit('users.json')
    create_file_if_not_exit('posts.json')

    with open('users.json', 'r+') as users_file, open('posts.json',
                                                      'r+') as posts_file:
        try:
            users = json.load(users_file)
        except JSONDecodeError:
            users = {}
        try:
            posts = json.load(posts_file)
        except JSONDecodeError:
            posts = {}
        if (not users) and (not posts):
            firstRun = True
        else:
            firstRun = False

        submissions = []

        # Getting all the considered posts and storing them
        for temp_submission in subreddit.new(limit=botConfig.look_back_posts):
            submissions.append(temp_submission)

        # We iterate through the post in reverse chronological order so the score are up to date for new posts
        for submission in reversed(submissions):
            try:
                submission_author = submission.author.name
                logger.info("looking at submission {} from {}".format(
                    submission.id, submission_author))
                if not submission.id in posts:
                    remove = False
                    remove_reason = ""
                    posts[submission.id] = {}
                    posts[submission.id]["feedbacks"] = []
                    logger.info('New post found {}'.format(submission.id))
                    if not submission_author in users:
                        remove = True
                        remove_reason = "lowScore"
                        users[submission_author] = {}
                        users[submission_author]["posts"] = 0
                        users[submission_author]["feedbacks"] = 0
                        author_history = users[submission_author]
                    else:
                        author_history = users[submission_author]
                        compiled_regex = map(lambda x: re.compile(x),
                                             botConfig.filter_regex)

                        if (author_history["posts"] +
                                1) * botConfig.score_needed > author_history[
                                    "feedbacks"]:
                            remove = True
                            remove_reason = "lowScore"
                        elif (any(
                                map(lambda x: x.match(submission.url),
                                    compiled_regex))):
                            logger.info(
                                submission.url +
                                'Should be removed for matching forbidden regex'
                            )
                            remove = True
                            remove_reason = "forbidden_regex"
                        else:
                            author_history[
                                "posts"] = author_history["posts"] + 1
                            users[submission_author] = author_history

                    if firstRun:
                        logger.info('recording the post for the first run')
                        author_history["posts"] = author_history["posts"] + 1
                        users[submission_author] = author_history
                    elif remove:
                        logger.info('Removing {} because {}'.format(
                            submission.id, remove_reason))
                        submission.mod.remove()
                        if remove_reason == "lowScore":
                            message = """
              Bleep bloop I'm a bot.\n
              Sorry your submission was removed.\n
              Your score is only {} and you need at least {} to post.\n
              You need to give feedback on at least {} track(s) and try again !\n
              *If you just gave enough feedback but your score wasn't credited, try again in a few minutes, the score update takes a little time*\n
              You can know your score at anytime by Direct Messaging me (the bot) with the word "SCORE" as a subject.\n
              Please repost your song once you have a score of {}.
              """.format(
                                author_history["feedbacks"] -
                                (author_history["posts"]) *
                                botConfig.score_needed, botConfig.score_needed,
                                botConfig.score_needed -
                                (author_history["feedbacks"] -
                                 (author_history["posts"]) *
                                 botConfig.score_needed),
                                botConfig.score_needed)
                        elif remove_reason == "forbidden_regex":
                            message = """
              Bleep bloop I'm a bot.\n
              Sorry your submission was removed.\n
              I detected that you were linking to a playlist... we only allow you to post one song at a time.\n
              Playlists are difficult to give feedback on, and this goes against the 1 song - {} comment system\n
              Please repost your music one song at a time and try again !
              """.format(botConfig.score_needed)
                        message = re.sub('\t', '', message)
                        submission.mod.send_removal_message(
                            message, title='submission removed', type='public')
                    else:
                        logger.info('Validating post {}'.format(submission.id))
                        message = """
            Bleep bloop I'm a bot.\n
            Your submission was approved u/{}, thank you for posting !\n
            You can know your score at anytime by Direct Messaging me (the bot) with the word "SCORE" as a subject.
            """.format(submission_author)
                        message = re.sub('\t', '', message)
                        submission.reply(message)

                # Looking at comments from post to register potential new feedback
                comments = submission.comments.list()
                submission_feedbackers = posts[submission.id]["feedbacks"]
                for comment in comments:
                    try:
                        comment_author = comment.author.name
                        if not comment_author == submission_author:
                            if not comment_author in users:
                                users[comment_author] = {}
                                users[comment_author]["posts"] = 0
                                users[comment_author]["feedbacks"] = 0
                            if not comment_author in submission_feedbackers and comment.banned_by == None:
                                logger.info(
                                    "new feedback from {} registered on {}".
                                    format(comment_author, submission.id))
                                if len(comment.body
                                       ) < botConfig.minimum_comment_length:
                                    logger.info(
                                        "new feedback is too short to be good")
                                    comment.reply_sort = 'new'
                                    comment.refresh()
                                    replies_authors = list(
                                        map(lambda x: x.author.name,
                                            comment.replies))
                                    if not "IndieFeedbackBot" in replies_authors:
                                        logger.info(
                                            "first time seen, commenting to let the author know"
                                        )
                                        msg_comment = """
                    Bleep bloop I'm a bot.\n
                    Sorry, this comment won't count in your score, because it's not at least {} characters long :/\n
                    """.format(minimum_comment_length)
                                        msg_comment = re.sub(
                                            '\t', '', msg_comment)
                                        comment.reply(msg_comment)
                                else:
                                    submission_feedbackers.append(
                                        comment_author)
                                    users[comment_author]["feedbacks"] = users[
                                        comment_author]["feedbacks"] + 1
                        feedbackers_set = set(submission_feedbackers)
                        posts[submission.id]["feedbacks"] = list(
                            feedbackers_set)
                    except:
                        logger.warning(
                            "comment registering went wrong {}".format(
                                str(comment)))
            except Exception as e:
                logger.warning(
                    "submission registering went wrong {} {}".format(
                        str(submission), e))

            save_changes(posts_file, posts, users_file, users)

        # Replying to DMs asking for score
        for message in reddit.inbox.unread(mark_read=True, limit=None):
            if isinstance(message, Message):
                message.mark_read()
                if message.subject.lower() == "score" or message.body.lower(
                ) == "score":
                    dm_author = message.author
                    print('Sending score DM to {}'.format(dm_author.name))
                    if dm_author.name in users:
                        dm_author_posts = users[dm_author.name]["posts"]
                        dm_author_feedbacks = users[
                            dm_author.name]["feedbacks"]
                        message.reply('Your score currently is {}'.format(
                            dm_author_feedbacks -
                            dm_author_posts * botConfig.score_needed))
                    else:
                        pass
                        message.reply('Your score currently is 0')
import inspect
import unittest
from datetime import time
from unittest import TestCase

from assertpy import assert_that
from timebetween import is_time_between

from bot_config import BotConfig
from discord_utils import choose_member_from, find_role, sanitize_env_vars, SAFE_KEYS, current_configuration, \
    SAFE_CONFIG_VARS, sanitize_config, health
from member import Member
from role import Role

test_config = BotConfig("discord token", "guild name", "bot name",
                        "started at", "heroku key")


class TestDiscordUtils(TestCase):
    def test_time(self):
        start = time(7, 0)
        end = time(19, 0)

        inside_of_interval = time(11, 0)
        outside_of_interval = time(20, 0)
        assert_that(is_time_between(inside_of_interval, start, end)).is_true()
        assert_that(is_time_between(outside_of_interval, start,
                                    end)).is_false()

    def test_choose_member(self):
        m1 = Member("foo")
Example #8
0
from PIL import Image

# load the example image and convert it to grayscale
import pytesseract
import util
from bot_config import BotConfig
from common import WINDOW_WIDTH, WINDOW_HEIGHT
from imagesearch import region_grabber, imagesearcharea, imagesearcharea_v2, region_grabber_v2
from util import click_image


class ImageNotFoundException(Exception):
    pass


IMAGE_FOLDER = BotConfig().get_property("General", "image_folder")

logger = util.get_logger()
# TODO test
import emu_manager

hwnd = emu_manager.get_instance(
    int(BotConfig().get_property("Emulator", "use_device")))


def find_text(text, x1, y1, x2, y2):
    import emu_manager
    hwnd = emu_manager.get_instance(
        int(BotConfig().get_property("Emulator", "use_device")))
    image = region_grabber_v2((x1, y1, x2, y2), hwnd)
    # image.save('testarea.png')  # useful for debugging purposes, this will save the captured region as "testarea.png"