def abort_game(update: Update, context: CallbackContext): chat_data = context.chat_data if "players" not in chat_data: chat_id = update.effective_chat.id lang = database.get_language_chat(chat_id) update.effective_message.reply_text(get_string(lang, "no_game_running")) return # sometimes a keyerror happens here. That can have different reasons, but this being an important command, I decided # to throw in an try expect try: lang = chat_data["lang"] except KeyError: lang = "en" chat_data["lang"] = "en" # little admin check if not is_admin(context.bot, update.effective_user.id, update.effective_chat): update.effective_message.reply_text(get_string(lang, "no_admin_abort")) return chat_id = update.effective_chat.id potential_job = context.job_queue.get_jobs_by_name(chat_id) if potential_job: potential_job[0].schedule_removal() chat_data.clear() update.effective_message.reply_text(get_string(lang, "abort_game")) chat_data["lang"] = lang
def wrapper(*args, **kwargs): update = args[0] context = args[1] user_id = update.effective_user.id user_data = context.user_data if "lang" not in user_data: lang = database.get_language_player(user_id) user_data["lang"] = lang else: lang = user_data["lang"] query = update.callback_query chat_id = int(query.data.split("_")[1]) try: chat = context.bot.get_chat(chat_id) except BadRequest: new_chat_id = database.get_new_id(chat_id) if new_chat_id: chat = context.bot.get_chat(chat_id) else: query.edit_message_text(get_string(lang, "group_not_found")) return if not helpers.is_admin(context.bot, update.effective_user.id, chat): query.edit_message_text(get_string(lang, "no_admin_settings")) return return func(*args, **kwargs)
def yes_game(context, data, chat_id, dp): chat_data = dp.chat_data[chat_id] lang = data["lang"] group_settings = data["group_settings"] deck = Deck(*group_settings["deck"].split("_")) chameleon = random.choice(list(data["players"])) random.shuffle(data["players"]) game_id = ''.join(random.choices(string.ascii_lowercase, k=10)) chat_data.update({"chameleon": chameleon, "secret": deck.secret, "players": data["players"], "lang": lang, "starter": data["starter"], "words": deck.words, "game_id": game_id, "fewer": group_settings["fewer"], "tournament": group_settings["tournament"], "more": group_settings["more"], "pin": group_settings["pin"], "restrict": {}, "deck": group_settings["deck"], "tutorial": data["tutorial"], "exclamation": group_settings["exclamation"]}) text = get_string(lang, "game_succeed").format(deck.topic, deck.word_list) button = InlineKeyboardMarkup([[InlineKeyboardButton(get_string(lang, "play_button"), callback_data="word" + game_id)]]) message = context.bot.send_message(chat_id, text, reply_to_message_id=data["message"], reply_markup=button, parse_mode=ParseMode.HTML) chat = None if group_settings["pin"] or group_settings["restrict"]: chat = context.bot.get_chat(chat_id) if group_settings["pin"]: pinned_message = chat.pinned_message if pinned_message: chat_data["pin"] = pinned_message.message_id try: context.bot.pin_chat_message(chat_id, message.message_id, True) except BadRequest as e: if e.message == "Not enough rights to pin a message": chat_data["pin"] = False database.insert_group_pin(chat_id) e.message += "handled in ghelper L48" raise e user = data["players"][0] text = get_string(lang, "first_player_say_word").format(mention_html(user["user_id"], user["first_name"])) if not group_settings["restrict"]: if group_settings["exclamation"]: text += "\n\n" + get_string(lang, "exclamation_activated") else: text += "\n\n" + get_string(lang, "exclamation_deactivated") context.bot.send_message(chat_id, text, reply_to_message_id=message.message_id, parse_mode=ParseMode.HTML) if group_settings["restrict"]: chat_data["restrict"]["initial_permissions"] = chat.permissions try: context.bot.set_chat_permissions(chat_id, ChatPermissions(can_send_messages=False)) if not is_admin(context.bot, user["user_id"], chat): context.bot.promote_chat_member(chat_id, user["user_id"], can_invite_users=True) chat_data["restrict"]["skip"] = False else: chat_data["restrict"]["skip"] = True except BadRequest as e: chat_data["restrict"] = False database.insert_group_restrict(chat_id) e.message += "handled in ghelper L68" raise e chat_data["word_list"] = message.message_id
def upload(update: Update, context: CallbackContext): if not is_admin(context.bot, update.effective_user.id, update.effective_chat): update.effective_message.reply_text("Sorry, admins only ;P") return if not update.effective_message.reply_to_message: update.effective_message.reply_text("You need to reply to a file... idiot") return file = update.effective_message.reply_to_message.document file_name = file.file_name if file_name.endswith(".yaml"): yaml_file(file, update, context.bot) elif file_name.endswith(".json"): json_file(file, update) else: update.effective_message.reply_text("You need to reply to a .yaml file... idiot") return
def start(update: Update, context: CallbackContext): user_id = update.effective_user.id database.insert_player_pm(user_id, True) user_data = context.user_data if "lang" not in user_data: lang = database.get_language_player(user_id) user_data["lang"] = lang else: lang = user_data["lang"] context.args = context.args[0].split("_") if context.args else None if not context.args or context.args[0] != "settings": return # not necessary, but pycharm won't believe me that... chat_id = 0 try: chat_id = int(context.args[1]) chat = context.bot.get_chat(chat_id) except ValueError: context.bot.send_message(user_id, get_string(lang, "group_not_found")) return except BadRequest: try: new_id = database.get_new_id(chat_id) if new_id: chat = context.bot.get_chat(int(new_id)) else: raise BadRequest except BadRequest: context.bot.send_message(user_id, get_string(lang, "group_not_found")) return database.insert_group_title(chat_id, chat.title, chat.link) if not helpers.is_admin(context.bot, update.effective_user.id, chat): update.effective_message.reply_text( get_string(lang, "no_admin_settings")) return buttons = group_settings_helpers.group_settings_buttons( get_string(lang, "group_setting_buttons"), chat_id) chat_link = helpers.chat_link(chat.title, chat.link) context.bot.send_message(user_id, get_string( lang, "group_setting_text").format(chat_link), reply_markup=InlineKeyboardMarkup(buttons), parse_mode=ParseMode.HTML, disable_web_page_preview=True)
def abort_game(update: Update, context: CallbackContext): chat_data = context.chat_data if "players" not in chat_data: chat_id = update.effective_chat.id lang = database.get_language_chat(chat_id) update.effective_message.reply_text(get_string(lang, "no_game_running")) return lang = chat_data["lang"] # little admin check if not is_admin(context.bot, update.effective_user.id, update.effective_chat): update.effective_message.reply_text(get_string(lang, "no_admin_abort")) return chat_id = update.effective_chat.id potential_job = context.job_queue.get_jobs_by_name(chat_id) if potential_job: potential_job[0].schedule_removal() chat_data.clear() update.effective_message.reply_text(get_string(lang, "abort_game")) chat_data["lang"] = lang
def group_setting(update: Update, context: CallbackContext): chat_id = update.effective_chat.id lang = database.get_language_chat(chat_id) if not helpers.is_admin(context.bot, update.effective_user.id, update.effective_chat): update.effective_message.reply_text( get_string(lang, "no_admin_settings")) return user_id = update.effective_user.id user_lang = database.get_language_player(user_id) pm = database.get_pm_player(user_id) context.user_data["lang"] = user_lang database.insert_group_title(chat_id, update.effective_chat.title, update.effective_chat.link) if pm: try: # yes, its not a string, I don't change the functions name for this you f****r chat_link = helpers.chat_link(update.effective_chat.title, update.effective_chat.link) buttons = group_settings_helpers.group_settings_buttons( get_string(user_lang, "group_setting_buttons"), chat_id) context.bot.send_message( user_id, get_string(user_lang, "group_setting_text").format(chat_link), reply_markup=InlineKeyboardMarkup(buttons), parse_mode=ParseMode.HTML, disable_web_page_preview=True) # this means the bot was blocked wtf except Unauthorized: update.effective_message.reply_text( get_string(lang, "admin_blocked_bot")) database.insert_player_pm(user_id, False) else: button = [[ InlineKeyboardButton( get_string(lang, "no_pm_settings_button"), url=f"https://t.me/thechameleonbot?start=settings_{chat_id}") ]] update.effective_message.reply_text( get_string(lang, "no_pm_settings"), reply_markup=InlineKeyboardMarkup(button))
def game_end(context, text, chat_id, chameleon_id, winner_ids, lang): chat_data = context.chat_data players = chat_data["players"] context.bot.send_message(chat_id, text, parse_mode=ParseMode.HTML, reply_markup=ReplyKeyboardRemove()) context.bot.edit_message_reply_markup(chat_id, chat_data["word_list"], reply_markup=None) player_ids = [] for player in players: player_ids.append(player["user_id"]) if chat_data["tournament"]: tournament = chat_data["tournament"] # first game of tournament if not isinstance(tournament, dict): database.end_game(chat_id, player_ids, chameleon_id, winner_ids, chat_data["starter"]["user_id"]) tournament = {} for player_id in player_ids: tournament[player_id] = 0 else: database.end_game(chat_id, player_ids, chameleon_id, winner_ids) # that means the chameleon won if len(winner_ids) == 1: # that means the chameleon had to guess, but won, so gets a point, no one else does if "guesses" in chat_data: tournament[chameleon_id] += 1 # that means the chameleon escaped undetected, so gets two points else: tournament[chameleon_id] += 2 # that means everyone else won, they get two points else: for user_id in winner_ids: if user_id is not chameleon_id: tournament[user_id] += 2 tournament_winners = [] for user_id in tournament: if tournament[user_id] >= 5: tournament_winners.append(user_id) # that means we have winner(s), the tournament is over if tournament_winners: database.end_tournament(chat_id, player_ids, tournament_winners) if len(tournament_winners) == 1: winner_mention = None contestant_mentions_points = [] for player in players: if player["user_id"] in tournament_winners: winner_mention = mention_html(player["user_id"], player["first_name"]) else: contestant_mentions_points.append( f"{mention_html(player['user_id'], player['first_name'])}: " f"<b>{tournament[player['user_id']]}</b>") text = get_string(lang, "tournament_end_one").format( winner_mention, tournament[tournament_winners[0]], "\n".join(contestant_mentions_points)) else: winner_mention_points = [] contestant_mentions_points = [] for player in players: if player["user_id"] in tournament_winners: winner_mention_points.append( f"{mention_html(player['user_id'], player['first_name'])}: " f"<b>{tournament[player['user_id']]}</b>") else: contestant_mentions_points.append( f"{mention_html(player['user_id'], player['first_name'])}: " f"<b>{tournament[player['user_id']]}</b>") text = get_string(lang, "tournament_end_several").format( "\n".join(winner_mention_points), "\n".join(contestant_mentions_points)) context.bot.send_message(chat_id, text, parse_mode=ParseMode.HTML) if chat_data["pin"]: if not isinstance(chat_data["pin"], bool): try: context.bot.pin_chat_message(chat_id, chat_data["pin"], True) except BadRequest as e: if e.message != "Not enough rights to pin a message": context.bot.unpin_chat_message(chat_id) e.message += "handled in game L363" else: chat_data["pin"] = False e.message += "handled in game L363, 2" raise e else: context.bot.unpin_chat_message(chat_id) chat_data.clear() chat_data["lang"] = lang # that means we dont, lets play another round else: chat_data["tournament"] = tournament for player in chat_data["players"]: player.pop("word", None) player.pop("votes", None) deck = Deck(chat_data["deck"]) chameleon = random.choice(list(chat_data["players"])) chat_data["players"] = chat_data["players"][1:] + [ chat_data["players"][0] ] game_id = ''.join(random.choices(string.ascii_lowercase, k=10)) chat_data.update({ "chameleon": chameleon, "secret": deck.secret, "game_id": game_id, "words": deck.words }) contestant_mentions_points = [] for player in players: contestant_mentions_points.append( f"{mention_html(player['user_id'], player['first_name'])}: " f"<b>{tournament[player['user_id']]}</b>") text = get_string(lang, "tournament_end").format( "\n".join(contestant_mentions_points), deck.topic, deck.word_list) button = InlineKeyboardMarkup([[ InlineKeyboardButton(get_string(lang, "play_button"), callback_data="word" + game_id) ]]) send_message = context.bot.send_message(chat_id, text, reply_markup=button, parse_mode=ParseMode.HTML) if chat_data["pin"]: context.bot.pin_chat_message(chat_id, send_message.message_id, True) user = chat_data["players"][0] text = get_string(lang, "first_player_say_word").format( mention_html(user["user_id"], user["first_name"])) if not chat_data["restrict"]: text += "\n\n" + get_string(lang, "say_word_not_restricted") context.bot.send_message( chat_id, text, reply_to_message_id=send_message.message_id, parse_mode=ParseMode.HTML) if chat_data["restrict"]: context.bot.set_chat_permissions( chat_id, ChatPermissions(can_send_messages=False)) if not is_admin(context.bot, user["user_id"], context.bot.get_chat(chat_id)): context.bot.promote_chat_member(chat_id, user["user_id"], can_invite_users=True) chat_data["restrict"]["skip"] = False else: chat_data["restrict"]["skip"] = True chat_data["word_list"] = send_message.message_id # we dont care if other values exist or not, but this is needed in calculating of our points, so we pop it chat_data.pop("guesses", None) chat_data.pop("voted", None) else: database.end_game(chat_id, player_ids, chameleon_id, winner_ids, chat_data["starter"]["user_id"]) if chat_data["pin"]: if not isinstance(chat_data["pin"], bool): try: context.bot.pin_chat_message(chat_id, chat_data["pin"], True) except BadRequest as e: if e.message != "Not enough rights to pin a message": context.bot.unpin_chat_message(chat_id) e.message += "handled in game L419" else: chat_data["pin"] = False e.message += "handled in game L419, 2" raise e else: context.bot.unpin_chat_message(chat_id) chat_data.clear() chat_data["lang"] = lang
def message(update: Update, context: CallbackContext): chat_data = context.chat_data # check if a game is running, could also be game_id or smth else if "chameleon" not in chat_data or "voted" in chat_data: return if not chat_data["restrict"]: if update.effective_message.text.startswith("!"): return user_id = update.effective_user.id if user_id not in [user["user_id"] for user in chat_data["players"]]: return chat_id = update.effective_chat.id lang = chat_data["lang"] players = chat_data["players"] done = False for index, player in enumerate(players): if "word" not in player: if user_id == player["user_id"]: word = update.effective_message.text players[index]["word"] = word try: next_player = players[index + 1] if chat_data["restrict"]: try: if not chat_data["restrict"]["skip"]: context.bot.promote_chat_member( chat_id, player["user_id"], can_invite_users=False) if not is_admin(context.bot, next_player["user_id"], update.effective_chat): context.bot.promote_chat_member( chat_id, next_player["user_id"], can_invite_users=True) chat_data["restrict"]["skip"] = False else: chat_data["restrict"]["skip"] = True except BadRequest as e: chat_data["restrict"] = False database.insert_group_restrict(chat_id) e.message += "handled in game, L50" raise e except IndexError: done = True if chat_data["restrict"]: try: if not chat_data["restrict"]["skip"]: context.bot.promote_chat_member( chat_id, player["user_id"], can_invite_users=False) context.bot.set_chat_permissions( chat_id, chat_data["restrict"]["initial_permissions"]) except BadRequest as e: chat_data["restrict"] = False database.insert_group_restrict(chat_id) e.message += "handled in game, L62" raise e break words = wordlist(players) restricted = "" if not chat_data["restrict"]: restricted = "\n\n" + get_string( lang, "say_word_not_restricted") text = get_string(lang, "more_players_say_word")\ .format(mention_html(next_player["user_id"], next_player["first_name"]), words, restricted) update.effective_message.reply_html(text) return else: break if done: chat_data["voted"] = [] words = wordlist(players) text = get_string(lang, "final_word_list").format(words) + "\n" + get_string( lang, "vote_list").format( player_mention_string(chat_data["players"])) buttons = vote_buttons(chat_data["players"], chat_data["game_id"]) v_message = update.effective_message.reply_html( text, reply_markup=InlineKeyboardMarkup(buttons), quote=False) if chat_data["pin"]: try: context.bot.pin_chat_message(chat_id, v_message.message_id, True) except BadRequest as e: chat_data["pin"] = False e.message += "handled in game L88" raise e
def message(update: Update, context: CallbackContext): chat_data = context.chat_data # check if a game is running, could also be game_id or smth else if "chameleon" not in chat_data or "voted" in chat_data: return # this means every message counts anyway if not chat_data["restrict"]: if update.effective_message.text.startswith("!"): # if the exclamation setting is deactivated, every message starting with an ! is ignored if not chat_data["exclamation"]: return else: # if the exclamation setting is activated, only messages starting with an ! are valid # lets remove the ! update.effective_message.text = update.effective_message.text[ 1:] else: # if the exclamation setting is activated, only messages starting with an ! are valid if chat_data["exclamation"]: return user_id = update.effective_user.id if user_id not in [user["user_id"] for user in chat_data["players"]]: return chat_id = update.effective_chat.id lang = chat_data["lang"] players = chat_data["players"] done = False for index, player in enumerate(players): if "word" not in player: if user_id == player["user_id"]: word = update.effective_message.text if len(word) > 103: if update.effective_message.link: word = f"<a href=\"{update.effective_message.link}\">{word[:100]}...</a>" else: word = f"{escape(word[:100])}..." else: word = escape(word) players[index]["word"] = word try: next_player = players[index + 1] if chat_data["restrict"]: try: if not chat_data["restrict"]["skip"]: context.bot.promote_chat_member( chat_id, player["user_id"], can_invite_users=False) if not is_admin(context.bot, next_player["user_id"], update.effective_chat): context.bot.promote_chat_member( chat_id, next_player["user_id"], can_invite_users=True) chat_data["restrict"]["skip"] = False else: chat_data["restrict"]["skip"] = True except BadRequest as e: chat_data["restrict"] = False database.insert_group_restrict(chat_id) e.message += "handled in game, L50" logger.info(e.message) except IndexError: done = True if chat_data["restrict"]: try: if not chat_data["restrict"]["skip"]: context.bot.promote_chat_member( chat_id, player["user_id"], can_invite_users=False) context.bot.set_chat_permissions( chat_id, chat_data["restrict"]["initial_permissions"]) except BadRequest as e: chat_data["restrict"] = False database.insert_group_restrict(chat_id) e.message += "handled in game, L62" logger.info(e.message) break words = wordlist(players) restricted = "" if not chat_data["restrict"]: if chat_data["exclamation"]: restricted += "\n\n" + get_string( lang, "exclamation_activated") else: restricted += "\n\n" + get_string( lang, "exclamation_deactivated") text = get_string(lang, "more_players_say_word")\ .format(mention_html(next_player["user_id"], next_player["first_name"]), words, restricted) update.effective_message.reply_html(text) return else: break if done: chat_data["voted"] = [] words = wordlist(players) text = get_string(lang, "final_word_list").format(words) + "\n" + get_string( lang, "vote_list").format( player_mention_string(chat_data["players"])) buttons = vote_buttons(chat_data["players"], chat_data["game_id"]) v_message = update.effective_message.reply_html( text, reply_markup=InlineKeyboardMarkup(buttons), reply_to_message_id=chat_data["word_list"]) if chat_data["pin"]: try: context.bot.pin_chat_message(chat_id, v_message.message_id, True) except BadRequest as e: chat_data["pin"] = False e.message += "handled in game L88" logger.info(e.message)