Exemple #1
0
 def cmd_link(self, bot: Bot, source: User, message: str, event: Any, **rest: Any) -> None:
     bot.send_message_to_user(
         source,
         self.settings["phrase_room_link"].format(room_name=self.settings["room_name"]),
         event,
         method="reply",
     )
Exemple #2
0
    def selftimeout(self, bot: Bot, source: User, event: Any, **rest) -> bool:
        if self.settings["subscribers_only"] and not source.subscriber:
            return True

        if self.settings["vip_only"] and not source.vip:
            return True

        if source.moderator is True:
            return True

        random_value = random.randint(self.settings["low_value"],
                                      self.settings["high_value"])
        standard_response = f"You got a {random_value}"

        if random_value == 0 and self.settings["zero_response"] != "":
            bot.send_message_to_user(
                source,
                f"{standard_response}. {self.settings['zero_response']}",
                event,
                method="reply")
        else:
            timeout_length = self.seconds_conversion(random_value)

            # Check if timeout value is over Twitch's maximum
            timeout_length = min(timeout_length, 1209600)

            bot.timeout(source,
                        timeout_length,
                        f"{standard_response}!",
                        once=True)

        return True
Exemple #3
0
    def status_duel(self, bot: Bot, source: User, **rest: Any) -> None:
        """
        Whispers you the current status of your active duel requests/duel targets

        How to use: !duelstatus
        """

        with DBManager.create_session_scope() as db_session:
            msg: List[str] = []
            if source.id in self.duel_requests:
                duelling = User.find_by_id(db_session,
                                           self.duel_requests[source.id])
                if duelling:
                    msg.append(
                        f"You have a duel request for {self.duel_request_price[source.id]} points by {duelling}"
                    )

            if source.id in self.duel_targets:
                challenger = User.find_by_id(db_session,
                                             self.duel_targets[source.id])
                if challenger:
                    msg.append(
                        f"You have a pending duel request from {challenger} for {self.duel_request_price[self.duel_targets[source.id]]} points"
                    )

            if len(msg) > 0:
                bot.whisper(source, ". ".join(msg))
            else:
                bot.whisper(
                    source,
                    "You have no duel request or duel target. Type !duel USERNAME POT to duel someone!"
                )
Exemple #4
0
    def show_emote(self, bot: Bot, source: User, args: Dict[str, Any], **rest: Any) -> bool:
        emote_instances = args["emote_instances"]

        if len(emote_instances) <= 0:
            # No emotes in the given message
            bot.whisper(source, "No valid emotes were found in your message.")
            return False

        first_emote = emote_instances[0].emote

        # request to show emote is ignored but return False ensures user is refunded tokens/points
        if not self.is_emote_allowed(first_emote.code):
            return False

        bot.websocket_manager.emit(
            "new_emotes",
            {
                "emotes": [first_emote.jsonify()],
                "opacity": self.settings["emote_opacity"],
                "persistence_time": self.settings["emote_persistence_time"],
                "scale": self.settings["emote_onscreen_scale"],
            },
        )

        if self.settings["success_whisper"]:
            bot.whisper(source, f"Successfully sent the emote {first_emote.code} to the stream!")

        return True
Exemple #5
0
    def get_duel_stats(bot: Bot, source: User, **rest: Any) -> None:
        """
        Whispers the users duel winratio to the user
        """
        if source.duel_stats is None:
            bot.whisper(source, "You have no recorded duels.")
            return True

        bot.whisper(
            source,
            f"duels: {source.duel_stats.duels_total} winrate: {source.duel_stats.winrate:.2f}% streak: {source.duel_stats.current_streak} profit: {source.duel_stats.profit}",
        )
Exemple #6
0
    def setUp(self):
        from pajbot.bot import Bot
        from pajbot.tbutil import load_config
        import datetime

        config = load_config('config.ini')
        args = Bot.parse_args()
        self.pajbot = Bot(config, args)
        self.source = self.pajbot.users['omgthisuserdoesnotexist123']
        self.source.username_raw = 'OmgthisuserdoesnotexiSt123'
        self.source.points = 142
        self.source.last_seen = datetime.datetime.strptime('17:01:42', '%H:%M:%S')
Exemple #7
0
    def add_link_whitelist(self, bot: Bot, source, message, **rest) -> bool:
        parts = message.split(" ")
        try:
            for link in parts:
                self.whitelist_url(link)
                AdminLogManager.post("Whitelist link added", source, link)
        except:
            log.exception("Unhandled exception in add_link")
            bot.whisper(source, "Some error occurred white adding your links")
            return False

        bot.whisper(source, "Successfully added your links")
        return True
Exemple #8
0
    def setUp(self):
        from pajbot.bot import Bot
        from pajbot.models.user import User, UserManager
        from pajbot.tbutil import load_config
        import datetime

        config = load_config('config.ini')
        args = Bot.parse_args()
        self.pajbot = Bot(config, args)
        self.source = self.pajbot.users['testuser123Kappa']
        self.source.username_raw = 'PajladA'
        self.source.points = 142
        self.source.last_seen = datetime.datetime.strptime(
            '17:01:42', '%H:%M:%S')
Exemple #9
0
def run(args):
    from pajbot.tbutil import load_config
    config = load_config(args.config)

    if 'main' not in config:
        log.error('Missing section [main] in config')
        sys.exit(1)

    if 'sql' in config:
        log.error(
            'The [sql] section in config is no longer used. See config.example.ini for the new format under [main].'
        )
        sys.exit(1)

    if 'db' not in config['main']:
        log.error('Missing required db config in the [main] section.')
        sys.exit(1)

    pajbot = Bot(config, args)

    pajbot.connect()

    def on_sigterm(signal, frame):
        pajbot.quit()
        sys.exit(0)

    signal.signal(signal.SIGTERM, on_sigterm)

    try:
        pajbot.start()
    except KeyboardInterrupt:
        pajbot.quit()
        pass
Exemple #10
0
    def decline_duel(self, bot: Bot, source: User, **options: Any) -> None:
        """
        Declines any active duel requests you've received.

        How to use: !decline
        """

        if source.id not in self.duel_targets:
            bot.whisper(source, "You are not being challenged to a duel")
            return

        with DBManager.create_session_scope() as db_session:
            requestor = User.find_by_id(db_session,
                                        self.duel_targets[source.id])

            if not requestor:
                bot.whisper(
                    source,
                    "Your challenge never existed, don't ask me what happened!"
                )
                return

            bot.whisper(source, f"You have declined the duel vs {requestor}")
            bot.whisper(requestor,
                        f"{source} declined the duel challenge with you.")

            del self.duel_targets[source.id]
            del self.duel_requests[requestor.id]
            del self.duel_request_price[requestor.id]
            del self.duel_begin_time[requestor.id]
Exemple #11
0
    def __init__(self, bot: Bot) -> None:
        super().__init__(bot)

        self.twitter_stream: Optional[MyStreamListener] = None

        if "twitter" not in bot.config:
            return

        try:
            if self.use_twitter_stream:
                self.check_twitter_connection()
                bot.execute_every(60 * 5, self.check_twitter_connection)
        except:
            log.exception("Twitter authentication failed.")
Exemple #12
0
def run(args):
    from pajbot.utils import load_config

    config = load_config(args.config)

    if "main" not in config:
        log.error("Missing section [main] in config")
        sys.exit(1)

    if "sql" in config:
        log.error(
            "The [sql] section in config is no longer used. See the example config for the new format under [main]."
        )
        sys.exit(1)

    if "db" not in config["main"]:
        log.error("Missing required db config in the [main] section.")
        sys.exit(1)

    pajbot = Bot(config, args)

    pajbot.connect()

    def on_sigterm(signal, frame):
        pajbot.quit_bot()
        sys.exit(0)

    signal.signal(signal.SIGTERM, on_sigterm)

    try:
        pajbot.start()
    except KeyboardInterrupt:
        pajbot.quit_bot()
Exemple #13
0
    def update_game(self, bot: Bot, source, message, **rest) -> Any:
        if not message:
            bot.say("You must specify a game to update to!")
            return

        # Resolve game name to game ID
        game: Optional[
            TwitchGame] = self.bot.twitch_helix_api.get_game_by_game_name(
                message)
        if not game:
            bot.say(f"Unable to find a game with the name '{message}'")
            return

        return self.generic_update(bot, source, message, "game",
                                   {"game_id": game.id})
Exemple #14
0
def apply_substitutions(text, substitutions: Dict[Any, Substitution], bot: Bot,
                        extra):
    for needle, sub in substitutions.items():
        if sub.key and sub.argument:
            param = sub.key
            extra["argument"] = MessageAction.get_argument_value(
                extra["message"], sub.argument - 1)
        elif sub.key:
            param = sub.key
        elif sub.argument:
            param = MessageAction.get_argument_value(extra["message"],
                                                     sub.argument - 1)
        else:
            log.error("Unknown param for response.")
            continue
        value: Any = sub.cb(param, extra)
        if value is None:
            return None
        try:
            for f in sub.filters:
                value = bot.apply_filter(value, f)
        except:
            log.exception("Exception caught in filter application")
        if value is None:
            return None
        text = text.replace(needle, str(value))

    return text
Exemple #15
0
def apply_substitutions(text, substitutions: Dict[Any, Substitution], bot: Bot,
                        extra):
    for needle, sub in substitutions.items():
        if sub.key and sub.argument:
            param = sub.key
            extra["argument"] = get_argument_value(extra["message"],
                                                   sub.argument)
        elif sub.key:
            param = sub.key
        elif sub.argument:
            param = get_argument_value(extra["message"], sub.argument)
        else:
            log.error("Unknown param for response.")
            continue
        # The dictionary of substitutions here will always come from get_substitutions, which means it will always have a callback to call
        assert sub.cb is not None
        value: Any = sub.cb(param, extra)
        try:
            for f in sub.filters:
                value = bot.apply_filter(value, f)
        except:
            log.exception("Exception caught in filter application")
        if value is None:
            return None
        text = text.replace(needle, str(value))

    return text
Exemple #16
0
def run(args):
    from pajbot.utils import load_config
    config = load_config(args.config)

    if 'main' not in config:
        log.error('Missing section [main] in config')
        sys.exit(1)

    if 'sql' in config:
        log.error('The [sql] section in config is no longer used. See config.example.ini for the new format under [main].')
        sys.exit(1)

    if 'db' not in config['main']:
        log.error('Missing required db config in the [main] section.')
        sys.exit(1)

    pajbot = Bot(config, args)

    pajbot.connect()

    def on_sigterm(signal, frame):
        pajbot.quit_bot()
        sys.exit(0)

    signal.signal(signal.SIGTERM, on_sigterm)

    try:
        pajbot.start()
    except KeyboardInterrupt:
        pajbot.quit_bot()
        pass
Exemple #17
0
    def setUp(self):
        from pajbot.bot import Bot
        from pajbot.models.user import User, UserManager
        from pajbot.tbutil import load_config
        import datetime

        config = load_config('config.ini')
        args = Bot.parse_args()
        self.pajbot = Bot(config, args)
        self.source = self.pajbot.users['testuser123Kappa']
        self.source.username_raw = 'PajladA'
        self.source.points = 142
        self.source.last_seen = datetime.datetime.strptime('17:01:42', '%H:%M:%S')
Exemple #18
0
    def generic_update(self, bot: Bot, source, message: str, field: str,
                       extra_args: Dict[str, str]) -> None:
        if not message:
            bot.say(f"You must specify a {field} to update to!")
            return

        if ("user:edit:broadcast"
                not in bot.streamer_access_token_manager.token.scope
                or not self.bot.twitch_helix_api.modify_channel_information(
                    self.bot.streamer_user_id,
                    authorization=bot.streamer_access_token_manager,
                    **extra_args,
                )):
            bot.say(
                "Error: The streamer grants permission to update the game. The streamer needs to be re-authenticated to fix this problem."
            )
            return

        log_msg = f'{source} updated the {field} to "{message}"'
        bot.say(log_msg)
        AdminLogManager.add_entry(f"{field.capitalize()} set", source, log_msg)
Exemple #19
0
    def cancel_duel(self, bot: Bot, source: User, **rest: Any) -> None:
        """
        Cancel any duel requests you've sent.

        How to use: !cancelduel
        """

        if source.id not in self.duel_requests:
            bot.whisper(source, "You have not sent any duel requests")
            return

        with DBManager.create_session_scope() as db_session:
            challenged = User.find_by_id(db_session,
                                         self.duel_requests[source.id])
            if not challenged:
                bot.whisper(source, "Could not find the user you challenged??")
                return

            bot.whisper(source, f"You have cancelled the duel vs {challenged}")

            del self.duel_targets[challenged.id]
            del self.duel_request_price[source.id]
            del self.duel_begin_time[source.id]
            del self.duel_requests[source.id]
Exemple #20
0
    def add_link_blacklist(self, bot: Bot, source, message, **rest) -> bool:
        options, new_links = self.parse_link_blacklist_arguments(message)

        if options is False:
            return False

        if new_links:
            parts = new_links.split(" ")
            try:
                for link in parts:
                    if len(link) > 1:
                        self.blacklist_url(link, **options)
                        AdminLogManager.post("Blacklist link added", source,
                                             link)
                bot.whisper(source, "Successfully added your links")
                return True
            except:
                log.exception("Unhandled exception in add_link_blacklist")
                bot.whisper(source,
                            "Some error occurred while adding your links")
                return False
        else:
            bot.whisper(source, "Usage: !add link blacklist LINK")
            return False
Exemple #21
0
    def update_title(self, bot: Bot, source, message, **rest) -> Any:
        auth_error = "Error: The streamer must grant permissions to update the title. The streamer needs to be re-authenticated to fix this problem."

        if ("user:edit:broadcast"
                not in bot.streamer_access_token_manager.token.scope
                and "channel:manage:broadcast"
                not in bot.streamer_access_token_manager.token.scope):
            bot.say(auth_error)
            return

        title = message

        if not title:
            bot.say("You must specify a title to update to!")
            return

        try:
            bot.twitch_helix_api.modify_channel_information(
                bot.streamer.id,
                {"title": title},
                authorization=bot.streamer_access_token_manager,
            )
        except HTTPError as e:
            if e.response.status_code == 401:
                log.error(f"Failed to update title to '{title}' - auth error")
                bot.say(auth_error)
                bot.streamer_access_token_manager.invalidate_token()
            elif e.response.status_code == 400:
                log.error(f"Title '{title}' contains banned words")
                bot.say(
                    f"{source}, Title contained banned words. Please remove the banned words and try again."
                )
            elif e.response.status_code == 500:
                log.error(
                    f"Failed to update title to '{title}' - internal server error"
                )
                bot.say(
                    f"{source}, Failed to update the title! Please try again.")
            else:
                log.exception(f"Unhandled HTTPError when updating to {title}")
            return

        log_msg = f'{source} updated the title to "{title}"'
        bot.say(log_msg)
        AdminLogManager.add_entry("Title set", source, log_msg)
Exemple #22
0
    def update_game(self, bot: Bot, source, message, **rest) -> Any:
        auth_error = "Error: The streamer must grant permissions to update the game. The streamer needs to be re-authenticated to fix this problem."

        if ("user:edit:broadcast"
                not in bot.streamer_access_token_manager.token.scope
                and "channel:manage:broadcast"
                not in bot.streamer_access_token_manager.token.scope):
            bot.say(auth_error)
            return

        game_name = message

        if not game_name:
            bot.say("You must specify a game to update to!")
            return

        # Resolve game name to game ID
        game = bot.twitch_helix_api.get_game_by_game_name(game_name)
        if not game:
            bot.say(f"Unable to find a game with the name '{game_name}'")
            return

        try:
            bot.twitch_helix_api.modify_channel_information(
                bot.streamer.id,
                {"game_id": game.id},
                authorization=bot.streamer_access_token_manager,
            )
        except HTTPError as e:
            if e.response.status_code == 401:
                log.error(
                    f"Failed to update game to '{game_name}' - auth error")
                bot.say(auth_error)
                bot.streamer_access_token_manager.invalidate_token()
            elif e.response.status_code == 500:
                log.error(
                    f"Failed to update game to '{game_name}' - internal server error"
                )
                bot.say(f"{source}, Failed to update game! Please try again.")
            else:
                log.exception(
                    f"Unhandled HTTPError when updating to {game_name}")
            return

        log_msg = f'{source} updated the game to "{game_name}"'
        bot.say(log_msg)
        AdminLogManager.add_entry("Game set", source, log_msg)
Exemple #23
0
    def initiate_duel(self, bot: Bot, source: User, message: str,
                      **rest: Any) -> bool:
        """
        Initiate a duel with a user.
        You can also bet points on the winner.
        By default, the maximum amount of points you can spend is 420.

        How to use: !duel USERNAME POINTS_TO_BET
        """

        if message is None:
            return False

        max_pot = self.settings["max_pot"]

        msg_split = message.split()
        input = msg_split[0]

        with DBManager.create_session_scope() as db_session:
            user = User.find_by_user_input(db_session, input)
            if user is None:
                # No user was found with this username
                return False

            duel_price = 0
            if len(msg_split) > 1:
                try:
                    duel_price = int(msg_split[1])
                    if duel_price < 0:
                        return False

                    if duel_price > max_pot:
                        duel_price = max_pot
                except ValueError:
                    pass

            if source.id in self.duel_requests:
                currently_duelling = User.find_by_id(
                    db_session, self.duel_requests[source.id])
                if currently_duelling is None:
                    del self.duel_requests[source.id]
                    return False

                bot.whisper(
                    source,
                    f"You already have a duel request active with {currently_duelling}. Type !cancelduel to cancel your duel request.",
                )
                return False

            if user == source:
                # You cannot duel yourself
                return False

            if user.last_active is None or (
                    utils.now() - user.last_active) > timedelta(minutes=5):
                bot.whisper(
                    source,
                    "This user has not been active in chat within the last 5 minutes. Get them to type in chat before sending another challenge",
                )
                return False

            if not user.can_afford(duel_price) or not source.can_afford(
                    duel_price):
                bot.whisper(
                    source,
                    f"You or your target do not have more than {duel_price} points, therefore you cannot duel for that amount.",
                )
                return False

            if user.id in self.duel_targets:
                challenged_by = User.find_by_id(db_session,
                                                self.duel_requests[user.id])
                bot.whisper(
                    source,
                    f"This person is already being challenged by {challenged_by}. Ask them to answer the offer by typing !deny or !accept",
                )
                return False

            self.duel_targets[user.id] = source.id
            self.duel_requests[source.id] = user.id
            self.duel_request_price[source.id] = duel_price
            self.duel_begin_time[source.id] = utils.now()
            bot.whisper(
                user,
                f"You have been challenged to a duel by {source} for {duel_price} points. You can either !accept or !deny this challenge.",
            )
            bot.whisper(source,
                        f"You have challenged {user} for {duel_price} points")

        return True
Exemple #24
0
    def accept_duel(self, bot: Bot, source: User, **rest: Any) -> None:
        """
        Accepts any active duel requests you've received.

        How to use: !accept
        """

        if source.id not in self.duel_targets:
            bot.whisper(source,
                        "You are not being challenged to a duel by anyone.")
            return

        with DBManager.create_session_scope() as db_session:
            requestor = User.find_by_id(db_session,
                                        self.duel_targets[source.id])
            if not requestor:
                bot.whisper(
                    source,
                    "The user who challenged you is gone, I don't know where they went!"
                )
                return

            duel_price = self.duel_request_price[self.duel_targets[source.id]]

            if not source.can_afford(duel_price) or not requestor.can_afford(
                    duel_price):
                bot.whisper(
                    source,
                    f"Your duel request with {requestor} was cancelled due to one of you not having enough points.",
                )
                bot.whisper(
                    requestor,
                    f"Your duel request with {source} was cancelled due to one of you not having enough points.",
                )

                del self.duel_requests[requestor.id]
                del self.duel_request_price[requestor.id]
                del self.duel_begin_time[requestor.id]
                del self.duel_targets[source.id]

                return

            source.points -= duel_price
            requestor.points -= duel_price
            winning_pot = int(duel_price *
                              (1.0 - self.settings["duel_tax"] / 100))
            participants = [source, requestor]
            winner = random.choice(participants)
            participants.remove(winner)
            loser = participants.pop()
            winner.points += duel_price
            winner.points += winning_pot

            # Persist duel statistics
            winner.duel_stats.won(winning_pot)
            loser.duel_stats.lost(duel_price)

            arguments = {
                "winner": winner.name,
                "loser": loser.name,
                "total_pot": duel_price,
                "extra_points": winning_pot,
            }

            if duel_price > 0:
                message = self.get_phrase("message_won_points", **arguments)
                if duel_price >= 500 and self.settings["show_on_clr"]:
                    bot.websocket_manager.emit(
                        "notification",
                        {"message": f"{winner} won the duel vs {loser}"})
            else:
                message = self.get_phrase("message_won", **arguments)
            bot.say(message)

            del self.duel_requests[requestor.id]
            del self.duel_request_price[requestor.id]
            del self.duel_begin_time[requestor.id]
            del self.duel_targets[source.id]

            HandlerManager.trigger("on_duel_complete",
                                   winner=winner,
                                   loser=loser,
                                   points_won=winning_pot,
                                   points_bet=duel_price)
Exemple #25
0
    def bingo_start(self, bot: Bot, source, message: str, event, args) -> bool:
        if self.bingo_running:
            bot.send_message_to_user(source,
                                     "A bingo is already running FailFish",
                                     event,
                                     method="reply")
            return False

        emote_instances = args["emote_instances"]
        known_sets = self.make_known_sets_dict(bot)

        selected_sets: Set[Tuple[str, Tuple[Emote, ...], bool]] = set()
        points_reward: Optional[int] = None
        unparsed_options = []

        words_in_message = [s for s in message.split(" ") if len(s) > 0]
        if len(words_in_message) <= 0:
            bot.send_message_to_user(
                source,
                "You must at least give me some emote sets or emotes to choose from! FailFish",
                event,
                method="reply",
            )
            return False

        emote_index_offset = len("!bingo start ")

        # we can't iterate using words_in_message here because that would mess up the accompanying index
        for index, word in iterate_split_with_index(message.split(" ")):
            if len(word) <= 0:
                continue

            # Is the current word an emote?
            potential_emote_instance = next(
                (e for e in emote_instances
                 if e.start == index + emote_index_offset), None)
            if potential_emote_instance is not None:
                # single-emote set with the name of the emote
                new_set = (potential_emote_instance.emote.code,
                           (potential_emote_instance.emote, ), True)
                selected_sets.add(new_set)
                continue

            parsed_int: Optional[int] = None

            # Is the current word a number?
            try:
                parsed_int = int(word)
            except ValueError:
                pass

            if parsed_int is not None:
                # if points_reward is already set this is the second number in the message
                if points_reward is not None:
                    unparsed_options.append(word)
                    continue
                points_reward = parsed_int
                continue

            # Is the current word a known set?
            cleaned_key = remove_emotes_suffix(word).lower()
            if cleaned_key in known_sets:
                selected_sets.add(known_sets[cleaned_key])
                continue

            unparsed_options.append(word)

        if len(unparsed_options) > 0:
            bot.say(
                "{}, I don't know what to do with the argument{} {} BabyRage".
                format(
                    source,
                    "" if len(unparsed_options) == 1 else "s",  # pluralization
                    join_to_sentence(['"' + s + '"'
                                      for s in unparsed_options]),
                ))
            return False

        default_points = self.settings["default_points"]
        if points_reward is None:
            points_reward = default_points

        max_points = self.settings["max_points"]
        if points_reward > max_points:
            bot.send_message_to_user(
                source,
                f"You can't start a bingo with that many points. FailFish {max_points} are allowed at most.",
                event,
                method="reply",
            )
            return False

        allow_negative_bingo = self.settings["allow_negative_bingo"]
        if points_reward < 0 and not allow_negative_bingo:
            bot.send_message_to_user(
                source,
                "You can't start a bingo with negative points. FailFish",
                event,
                method="reply")
            return False

        min_points = -self.settings["max_negative_points"]
        if points_reward < min_points:
            bot.send_message_to_user(
                source,
                "You can't start a bingo with that many negative points. FailFish {min_points} are allowed at most.",
                event,
                method="reply",
            )
            return False

        if len(selected_sets) <= 0:
            bot.send_message_to_user(
                source,
                "You must at least give me some emotes or emote sets to choose from! FailFish",
                event,
                method="reply",
            )
            return False

        selected_set_names = []
        selected_discrete_emote_codes = []
        selected_emotes: Set[Emote] = set()
        for set_name, set_emotes, is_discrete_emote in selected_sets:
            if is_discrete_emote:
                selected_discrete_emote_codes.append(set_name)
            else:
                selected_set_names.append(set_name)
            selected_emotes.update(set_emotes)

        correct_emote = random.choice(list(selected_emotes))

        user_messages = []
        if len(selected_set_names) > 0:
            user_messages.append(join_to_sentence(selected_set_names))

        if len(selected_discrete_emote_codes) > 0:
            # the space at the end is so the ! from the below message doesn't stop the last emote from showing up in chat
            user_messages.append(
                f"these emotes: {' '.join(selected_discrete_emote_codes)} ")

        bot.me(
            f"A bingo has started! ThunBeast Guess the right emote to win {points_reward} points! B) Only one emote per message! Select from {' and '.join(user_messages)}!"
        )

        log.info(
            f"A Bingo game has begun for {points_reward} points, correct emote is {correct_emote}"
        )
        self.active_game = BingoGame(correct_emote, points_reward)

        return True
Exemple #26
0
    pajbot = Bot(config, args)

    pajbot.connect()

    def on_sigterm(signal, frame):
        pajbot.quit_bot()
        sys.exit(0)

    signal.signal(signal.SIGTERM, on_sigterm)

    try:
        pajbot.start()
    except KeyboardInterrupt:
        pajbot.quit_bot()
        pass


def handle_exceptions(exctype, value, tb):
    log.error('Logging an uncaught exception', exc_info=(exctype, value, tb))

if __name__ == '__main__':
    from pajbot.utils import init_logging

    sys.excepthook = handle_exceptions

    args = Bot.parse_args()

    init_logging('pajbot')
    run(args)
Exemple #27
0
    pajbot = Bot(config, args)

    pajbot.connect()

    def on_sigterm(signal, frame):
        pajbot.quit()
        sys.exit(0)

    signal.signal(signal.SIGTERM, on_sigterm)

    try:
        pajbot.start()
    except KeyboardInterrupt:
        pajbot.quit()
        pass


def handle_exceptions(exctype, value, tb):
    log.error('Logging an uncaught exception', exc_info=(exctype, value, tb))


if __name__ == "__main__":
    from pajbot.tbutil import init_logging

    sys.excepthook = handle_exceptions

    args = Bot.parse_args()

    init_logging('pajbot')
    run(args)