def add_teacher(bot, update): """ Фукнция добавления учителя """ mes = update.message academy = Guild.get_guild(guild_tag="АКАДЕМИЯ") if academy is None: bot.send_message(chat_id=mes.chat_id, text="Академия не найдена. Обратитесь к @Cactiw") return player = Player.get_player(mes.from_user.id) if player is None: return if player.id != academy.commander_id: bot.send_message(chat_id=update.message.chat_id, text="Только глава академии может добавлять учителей.") return if mes.reply_to_message is None: bot.send_message(chat_id=update.message.chat_id, text="Сообщение должно являться ответом на сообщение игрока, " "которого необходимо сделать учителем.") return player_to_add = Player.get_player(update.message.reply_to_message.from_user.id) if player_to_add is None: bot.send_message(chat_id=update.message.chat_id, text="Игрок для добавления не найден.") return if academy.check_high_access(player_to_add.id): bot.send_message(chat_id=update.message.chat_id, text="Игрок уже имеет необходимые права.") return academy.assistants.append(player_to_add.id) academy.update_to_database() bot.send_message(chat_id=update.message.chat_id, text="<b>{}</b> теперь учитель!".format(player_to_add.nickname), parse_mode='HTML', reply_to_message_id=update.message.message_id)
def two_action_timeout(bot, cur_job): player_id, pair_player_id = cur_job.context.get("ids") player, pair_player = Player.get_player(player_id), Player.get_player(pair_player_id) user_data, pair_user_data = dispatcher.user_data.get(player_id), dispatcher.user_data.get(pair_player_id) status, quest = user_data.get("status"), user_data.get("quest") if status != "two_quest": return qst = quest_texts[quest]["two_players"][user_data["quest_id"]] first_text = qst.get("first_fail") second_text = qst.get("second_fail") or first_text return_from_quest(player_id, user_data) return_from_quest(pair_player_id, pair_user_data) player.reputation += GO_NOT_SUCCESS_REPUTATION pair_player.reputation += GO_NOT_SUCCESS_REPUTATION player.update() pair_player.update() buttons = get_general_buttons(user_data, player) bot.send_message(chat_id=player_id, text=first_text + "\nПолучено {}🔘".format(GO_NOT_SUCCESS_REPUTATION), reply_markup=buttons) bot.send_message(chat_id=pair_player_id, text=second_text + "\nПолучено {}🔘".format(GO_NOT_SUCCESS_REPUTATION), reply_markup=buttons) now = datetime.datetime.now(tz=moscow_tz).replace(tzinfo=None) request = "insert into castle_logs(player_id, action, result, date, additional_info) values (%s, %s, %s, %s, %s)" cursor.execute(request, (player.id, quest, 2, now, json.dumps({"result": "two_players_fail", "pair_player_id": pair_player_id}))) cursor.execute(request, (pair_player_id, quest, 2, now, json.dumps({"result": "two_players_fail", "pair_player_id": player.id})))
def count_reputation_sum(bot, update): """ Функция для отлавливания багов и их использования. Команда /count_reputation_sum Выводит разницу между полученными "легально" жетонами и текущими жетонами у игроков. """ request = "select action, player_id from castle_logs" cursor.execute(request) rep = {} action_to_rep = {"collect_resources": 3, "construction": 5} row = cursor.fetchone() while row is not None: action, player_id = row cur_rep = rep.get(player_id) or 0 cur_rep += action_to_rep.get(action) rep.update({player_id: cur_rep}) row = cursor.fetchone() lst = list(rep.items()) lst.sort(key=lambda x: Player.get_player(x[0]).reputation - x[1], reverse=True) response = "Статистика по жетонам:\n" for obj in lst: id, reputation = obj player = Player.get_player(id) new_response = "<code>{:<20}</code> 🔘: <code>{:4<}</code>, всего 🔘: <code>{:<4}</code>, <code>{}</code>\n" \ "".format(player.username, reputation, player.reputation, player.reputation - reputation) if len(response + new_response) > 4000: bot.send_message(chat_id=update.message.chat_id, text=response, parse_mode='HTML') response = "" response += new_response bot.send_message(chat_id=update.message.chat_id, text=response, parse_mode='HTML')
def two_go_action(bot, cur_job): quest, player_id = cur_job.context.get("quest"), cur_job.context.get("player_id") player = Player.get_player(player_id) user_data = dispatcher.user_data.get(player_id) status = user_data.get("status") if status != quest: return with quest_lock: player_list = quest_players.get(quest) if player_list is None: logging.error("No quest configured for {}".format(quest)) return if not player_list: player_list.append(player_id) safe_job_create(player_awaiting_timeout, 60 * 3, player.id, context={"quest": quest, "player_id": player.id}) user_data.update({"status": "waiting_second_player_for_quest"}) return else: pair_player_id = player_list.pop() pair_player = Player.get_player(pair_player_id) pair_user_data = dispatcher.user_data.get(pair_player_id) quest_id, qst = random.choice(list(quest_texts[quest]["two_players"].items())) user_data.update({"status": "two_quest", "pair_id": pair_player_id, "quest": quest, "quest_id": quest_id}) pair_user_data.update({"status": "two_quest", "pair_id": player_id, "quest": quest, "quest_id": quest_id}) first_text = qst["first_begin"] second_text = qst.get("second_begin") or first_text bot.send_message(chat_id=player_id, text=first_text.format(pair_player.nickname, pair_player.username), parse_mode='HTML') bot.send_message(chat_id=pair_player_id, text=second_text.format(player.nickname, player.username), parse_mode='HTML') safe_job_create(two_action_timeout, 30, player.id, {"ids": [player_id, pair_player_id]})
def del_teacher(bot, update): """ Функция удаления учителя """ mes = update.message academy = Guild.get_guild(guild_tag="АКАДЕМИЯ") if academy is None: bot.send_message(chat_id=mes.chat_id, text="Академия не найдена. Обратитесь к @Cactiw") return player = Player.get_player(mes.from_user.id) if player is None: return if player.id != academy.commander_id: bot.send_message(chat_id=update.message.chat_id, text="Только глава академии может удалять учителей.") return if mes.reply_to_message is None: bot.send_message(chat_id=update.message.chat_id, text="Сообщение должно являться ответом на сообщение игрока, " "которого необходимо снять с должности учителя.") return player_to_add = Player.get_player(update.message.reply_to_message.from_user.id) if player_to_add is None: bot.send_message(chat_id=update.message.chat_id, text="Игрок для удаления не найден.") return if academy.commander_id == player_to_add.id: bot.send_message(chat_id=update.message.chat_id, text="Нельзя снять главу академии.") return if not academy.check_high_access(player_to_add.id): bot.send_message(chat_id=update.message.chat_id, text="Игрок и так не учитель.") return academy.assistants.remove(player_to_add.id) academy.update_to_database() bot.send_message(chat_id=update.message.chat_id, text="<b>{}</b> больше не учитель!".format(player_to_add.nickname), parse_mode='HTML', reply_to_message_id=update.message.message_id)
def alliance_stats(bot, update): mes = update.callback_query.message data = update.callback_query.data alliance_id = int(re.search("_(\\d+)", data).group(1)) player = Player.get_player(update.callback_query.from_user.id) player_guild = Guild.get_guild(player.guild) if not player_guild.check_high_access(player.id): bot.answerCallbackQuery(update.callback_query.id, text="Данная функция доступна только командирам гильдий и их заместителям.", show_alert=True) return alliance = Alliance.get_player_alliance(player) if alliance is None or alliance.id != alliance_id: bot.answerCallbackQuery(update.callback_query.id, text="Альянс не соответствует Вашему. Начните сначала.", show_alert=True) return guilds = alliance.get_alliance_guilds() response = "📊Статистика <b>{}</b>:\n".format(alliance.name) total_stats = [[0, 0, 0], [0, 0, 0], [0, 0, 0]] for guild in guilds: stats = reduce( add_player_stats, map(lambda player_id: Player.get_player(player_id), guild.members), [[0, 0, 0], [0, 0, 0], [0, 0, 0]] ) response += "<b>{}</b>\n{}\n".format(guild.tag, format_leagues_stats(stats)) total_stats = add_stats_to_total(total_stats, stats) response += "\n<b>Всего:</b>\n{}\n".format(format_leagues_stats(total_stats)) bot.send_message(chat_id=mes.chat_id, text=response, parse_mode='HTML') bot.answerCallbackQuery(update.callback_query.id)
def view_guild_players_in_union(bot, update): mes = update.message if not filter_is_pm(mes): bot.send_message( chat_id=mes.chat_id, text="Команда разрешена только в лс, чтобы не пинговать людей.", reply_to_message_id=mes.message_id) return curr_player = Player.get_player(mes.from_user.id) if curr_player is None: return guild_id = curr_player.guild if guild_id is None: bot.send_message( chat_id=mes.chat_id, text= "Вы не состоите в гильдии. Вступите в гильдию в игре и попросите " "командира добавить вас в гильдейском чате.") return guild = Guild.get_guild(guild_id=guild_id) if guild is None: bot.send_message(chat_id=mes.chat_id, text="Гильдия не найдена.") return if not guild.check_high_access(curr_player.id): bot.send_message( chat_id=mes.chat_id, text="Только замы и гм могут использовать эту команду.") return union_name = re.search(" (.*)", mes.text) if union_name is None: bot.send_message( chat_id=mes.chat_id, text="Неверный синтаксис. Укажите название профсоюза после команды." ) return union_name = union_name.group(1) union = TradeUnion.get_union(union_name=union_name) if union is None: bot.send_message( chat_id=mes.chat_id, text="Профсоюз не найден. Проверьте правильность ввода его имени.") return not_in_union = [] response = "Список игроков в гильдии <b>{}</b> в профсоюзе <b>{}</b>\n".format( guild.tag, union.name) for player_id in guild.members: player = Player.get_player(player_id, notify_on_error=False) if player is None: continue if player_id in union.players: response += "<b>{}</b> — @{}\n".format(player.nickname, player.username) else: not_in_union.append(player) response += "\nВ других профсоюзах или без него:\n" for player in not_in_union: response += "<b>{}</b> — @{}\n".format(player.nickname, player.username) bot.send_message(chat_id=mes.chat_id, text=response, parse_mode='HTML')
def view_guild_unions(bot, update): mes = update.message if not filter_is_pm(mes): bot.send_message( chat_id=mes.chat_id, text="Команда разрешена только в лс, чтобы не пинговать людей.", reply_to_message_id=mes.message_id) return curr_player = Player.get_player(mes.from_user.id) if curr_player is None: return guild_id = curr_player.guild if guild_id is None: bot.send_message( chat_id=mes.chat_id, text= "Вы не состоите в гильдии. Вступите в гильдию в игре и попросите " "командира добавить вас в гильдейском чате.") return guild = Guild.get_guild(guild_id=guild_id) if guild is None: bot.send_message(chat_id=mes.chat_id, text="Гильдия не найдена.") return if not guild.check_high_access(curr_player.id): bot.send_message( chat_id=mes.chat_id, text="Только замы и гм могут использовать эту команду.") return union_id = 1 union = TradeUnion.get_union(union_id=union_id) players_in_unions = {} while union is not None: union_players_list = [] players_in_unions.update({union.name: union_players_list}) for player_id in guild.members: player = Player.get_player(player_id, notify_on_error=False) if player is None: continue if player_id in union.players: union_players_list.append(player) union_id += 1 union = TradeUnion.get_union(union_id=union_id) response = "Список игроков в гильдии <b>{}</b> в профсоюзах\n".format( guild.tag) for player_id in guild.members: player = Player.get_player(player_id, notify_on_error=False) if player is None: continue found = False for un, lst in list(players_in_unions.items()): if player in lst: response += "<b>{}</b> — @{} — <b>{}</b>\n".format( player.nickname, player.username, un) found = True break if not found: response += "<b>{}</b> — @{} — НЕТ ПРОФСОЮЗА\n".format( player.nickname, player.username) bot.send_message(chat_id=mes.chat_id, text=response, parse_mode='HTML')
def get_player_stats_text(player: Player, forward_message_date, ping): if player is None or player.api_info.get("token") is None: return "" response = "Отправивший игрок:\n{}\n".format(player.format_mobs_stats(forward_message_date, bool(ping))) if ping: response += "\nПодходящие игроки чата:\n" for player in ping: response += "{}\n".format(player.format_mobs_stats(forward_message_date)) return response
def fight_club(bot, update): mes = update.message link = re.search("/fight_(.*)$", mes.text) if link is None: bot.send_message(chat_id=mes.chat_id, text="Ошибка.") return link = link.group(1) player = Player.get_player(mes.from_user.id) try: forward_message_date = utc.localize(mes.forward_date).astimezone(tz=moscow_tz).replace(tzinfo=None) except Exception: forward_message_date = datetime.datetime.now(tz=moscow_tz).replace(tzinfo=None) request = "select mob_lvls, helpers from mobs where link = %s" cursor.execute(request, (link,)) row = cursor.fetchone() helpers = [] lvl = player.lvl if row is not None: lvls, helpers = row lvl = lvls[0] response = get_fight_club_txt(link, lvl, helpers, forward_message_date) buttons = [[InlineKeyboardButton(text="⚔ {}-{}🏅".format(int(lvl - 5), int(lvl + 10)), url=u"https://t.me/share/url?url=/fight_{}".format(link)), InlineKeyboardButton(text="🤝Помогаю!", callback_data="fight_club_partify_{}".format(link))]] guild = Guild.get_guild(chat_id=mes.chat_id) if guild is not None: ping = [] for player_id in guild.members: cur_player = Player.get_player(player_id) if cur_player is None: continue if cur_player.settings.get("pretend") and cur_player.lvl in range(lvl - 5, lvl + 11) and \ player.username not in ping: ping.append(player.username) if len(ping) >= 4: text = "Подпольный бой!\n" for username in ping: text += "@{} ".format(username) bot.send_message(chat_id=mes.chat_id, text=text) ping.clear() if ping: text = "Подпольный бой!\n" for username in ping: text += "@{} ".format(username) bot.send_message(chat_id=mes.chat_id, text=text) if guild is not None: response += "\n\n<em>Подписаться на уведомления о клубах в чате ги:</em> /pretend" bot.send_message(chat_id=mes.chat_id, text=response, reply_markup=InlineKeyboardMarkup(buttons), parse_mode='HTML') request = "insert into mobs(link, mob_names, mob_lvls, date_created, created_player) values (" \ "%s, %s, %s, %s, %s)" try: cursor.execute(request, (link, ["Fight Club"], [lvl], forward_message_date, mes.from_user.id)) except psycopg2.IntegrityError: pass
def view_alliance(bot, update): mes = update.message player = Player.get_player(mes.from_user.id) player_guild = Guild.get_guild(player.guild) alliance = Alliance.get_player_alliance(player) guilds = alliance.get_alliance_guilds() res = "🤝<b>{}</b>\n".format(alliance.name) res += "Владелец: {}\n".format(Player.get_player(alliance.creator_id).nickname) res += "Гильдии альянса: {}".format(" ".join(map(lambda guild: "{}[{}]".format(guild.castle, guild.tag), guilds))) buttons = None if player_guild.check_high_access(player.id): buttons = InlineKeyboardMarkup(get_alliance_inline_buttons(alliance)) bot.send_message(chat_id=mes.chat_id, text=res, parse_mode='HTML', reply_markup=buttons)
def two_quest_pressed_go(bot, update, user_data: dict): mes = update.message pair_player_id, quest = user_data.get("pair_id"), user_data.get("quest") pair_user_data = dispatcher.user_data.get(pair_player_id) if pair_user_data is None: logging.error("Pair user_data is None for {}".format(mes.from_user.id)) return try: j = construction_jobs.get(mes.from_user.id) if j is None: j = construction_jobs.get(pair_player_id) j.job.schedule_removal() except Exception: logging.error(traceback.format_exc()) pressed = pair_user_data.get("quest_pressed") if not pressed: # Нажал первый игрок (ждём второго) user_data.update({"quest_pressed": True}) safe_job_create(two_action_timeout, 30, mes.from_user.id, {"ids": [mes.from_user.id, pair_player_id]}) bot.send_message(chat_id=mes.from_user.id, text="Принято! Ожидайте соратника.") return # Нажали оба игрока player, pair_player = Player.get_player(mes.from_user.id), Player.get_player(pair_player_id) qst = quest_texts[quest]["two_players"][user_data["quest_id"]] first_text = qst.get("first_success") second_text = qst.get("second_success") or first_text return_from_quest(player.id, user_data) return_from_quest(pair_player.id, pair_user_data) player.reputation += GO_NOT_SUCCESS_REPUTATION pair_player.reputation += GO_NOT_SUCCESS_REPUTATION player.update() pair_player.update() buttons = get_general_buttons(user_data, player) bot.send_message(chat_id=player.id, text=first_text + "\nПолучено {}🔘".format(GO_SUCCESS_REPUTATION), reply_markup=buttons) bot.send_message(chat_id=pair_player_id, text=second_text + "\nПолучено {}🔘".format(GO_SUCCESS_REPUTATION), reply_markup=buttons) now = datetime.datetime.now(tz=moscow_tz).replace(tzinfo=None) request = "insert into castle_logs(player_id, action, result, date, additional_info) values (%s, %s, %s, %s, %s)" cursor.execute(request, (player.id, quest, 1, now, json.dumps({"result": "two_players_success", "pair_player_id": pair_player_id}))) cursor.execute(request, (pair_player_id, quest, 1, now, json.dumps({"result": "two_players_success", "pair_player_id": player.id})))
def get_portraits_text(portrait_num: int = 0): response = "Стены замка увешаны портретами текущих генералов Скалы:\n" for user_id in high_access_list: player = Player.get_player(user_id, notify_on_error=False) if player is None: continue response += "@{} - <b>{}</b>\n".format(player.username, player.nickname) player = Player.get_player(high_access_list[portrait_num]) if player is None: player = Player.get_player(high_access_list[0]) response += "\n<a href=\"https://t.me/{}\">{}</a>".format( player.username, player.nickname) return response
def alliance_pin(bot, update): player = Player.get_player(update.message.from_user.id) alliance = Alliance.get_player_alliance(player) new_text: str = update.message.text changed = False parse = re.findall("/ga_((atk|def)_(\\w+)|def)", update.message.text) for full, cmd, link in parse: location = AllianceLocation.get_location_by_link(link) if location is None: self = False if full == "def" and link == '': cur_alliance = alliance cmd = "def" self = True else: cur_alliance = Alliance.get_alliance_by_link(link) if cur_alliance is None: continue new_text = re.sub("/ga_{}_{}()".format(cmd, link) if not self else "/ga_def([^\\_]|$)", "<a href=\"t.me/share/url?url=/ga_{}_{}\">{}{}</a>\\g<1>".format( cmd, cur_alliance.link, "⚔️" if cmd == "atk" else "🛡", cur_alliance.name), new_text) changed = True else: new_text = re.sub("/ga_{}_{}".format(cmd, link), "<a href=\"t.me/share/url?url=/ga_{}_{}\">{}{}</a>".format( cmd, link, "⚔️" if cmd == "atk" else "🛡", location.format_name()), new_text) changed = True # if cur_alliance == alliance: if changed: bot.send_message(chat_id=update.message.chat_id, text=new_text, parse_mode='HTML', reply_to_message_id=update.message.message_id)
def request_get_reward(bot, update, user_data): mes = update.message reward = rewards.get(mes.text[1:]) player = Player.get_player(mes.from_user.id) if player is None: return if reward is None: bot.send_message(chat_id=mes.chat_id, text="Неверный синтаксис.") return if player.reputation < reward["price"]: bot.send_message(chat_id=mes.chat_id, text="Недостаточно 🔘 жетонов") return if reward.get("skip_enter_text"): # Ничего вводть не надо, сразу на подтверждение кидаю user_data.update({ "status": "tea_party", "reward": mes.text[1:], "reward_text": reward.get("text") }) request_reward_confirmation(bot, mes, reward, user_data) else: # Запрос ввода текста для награды user_data.update({ "status": "requested_reward", "reward": mes.text[1:] }) bot.send_message(chat_id=mes.chat_id, text=reward["text"])
def reward_read_only(player, reward, cost, *args, **kwargs): mute_player = Player.get_player(reward) if mute_player is None: player.reputation += cost player.update() dispatcher.bot.send_message(player.id, text="Игрок не найден. Жетоны возвращены.") return if check_access(mute_player.id): # Хотят забанить чела из мида muted_players.update( {mute_player.id: time.time() + FORBID_MUTED_MINUTES * 60}) dispatcher.bot.send_message( chat_id=mute_player.id, text= "Ты протягиваешь кошель с жетонами стражнику, шепча на ухо имя бедолаги.\n" "-\"ШО, ПРЯМ СОВЕТНИКА КОРОЛЯ, ЗА ТАКИЕ-ТО ДЕНЬГИ?!\"\n" "Стражники скручивают тебя и кидают в темницу. Пять минуток " "посидишь - поумнеешь.") else: muted_players.update( {mute_player.id: time.time() + MUTED_MINUTES * 60}) dispatcher.bot.send_message( chat_id=mute_player.id, text= "\"Стражу подкупили!\" - кричишь ты, пока тебя утаскивают в одиночку " "на ближайшие пол часа.\nОтличное время подумать, где и когда ты умудрился " "нажить себе врагов, что аж жетонов не пожалели, чтобы тебе насолить.\n" "<em>30 минут вы не можете ничего писать в чатах с ботом.</em>", parse_mode='HTML')
def new_autospend_rule(bot, update, user_data): player = Player.get_player(update.message.from_user.id) try: resource_code, max_gold = update.message.text.split() except (ValueError, TypeError): bot.send_message(chat_id=player.id, text="Неверный синтаксис.") return resource_name = get_resource_name_by_code(resource_code) if resource_name is None: bot.send_message(chat_id=player.id, text="Ресурс не найден. Повторите попытку.") return try: max_gold = int(max_gold) if max_gold <= 0 or max_gold > 1000: raise ValueError except ValueError: bot.send_message( chat_id=player.id, text="Цена должна быть положительным числом, не больше 1000.") return rules = player.api_info.get("autospend_rules", []) new_rules = list(filter(lambda rule: rule[0] != resource_code, rules)) new_rules.append([resource_code, max_gold]) player.api_info.update({"autospend_rules": new_rules}) player.update() user_data.pop("status") autospend_gold(bot, update, start_text="✅Правило добавлено!\n\n")
def set_craft_possible_tier(bot, update, user_data): mes = update.callback_query.message data = update.callback_query.data player = Player.get_player(update.callback_query.from_user.id) guild = Guild.get_guild(player.guild) guild_stock = guild.get_stock() if guild is not None else {} stock = merge_int_dictionaries(player.stock.copy(), guild_stock.copy()) parse = re.search("craft_possible_tier_(\\d+)", data) if parse is None: bot.answerCallbackQuery( callback_query_id=update.callback_query.id, show_alert=True, text="Произошла ошибка. Попробуйте начать сначала.") return tier = user_data.get("craft_possible_tier") new_tier = int(parse.group(1)) if tier == new_tier: new_tier = None pop_from_user_data_if_presented(user_data, "craft_possible_tier") else: user_data.update({"craft_possible_tier": new_tier}) res = get_possible_text(stock, tier=new_tier) buttons = InlineKeyboardMarkup(get_possible_buttons(new_tier)) try: bot.editMessageText(chat_id=mes.chat_id, message_id=mes.message_id, text=res, reply_markup=buttons, parse_mode='HTML') except Exception: logging.error(traceback.format_exc()) bot.answerCallbackQuery(callback_query_id=update.callback_query.id, text="Готово!")
def repair(bot, update): """ Показывает список лавок с открытым обслуживанием (команда /repair) """ mes = update.message shops = cwapi.api_info.get("shops") if shops is None or not shops: bot.send_message(chat_id=mes.chat_id, text="Нет данных о магазинах. Ожидайте обновления.") return player = Player.get_player(mes.from_user.id) player_castle = player.castle if player is not None else '🖤' sh = [] for shop in shops: if shop.get("maintenanceEnabled"): sh.append(shop) sh.sort(key=lambda x: repair_comparator(x, player_castle), reverse=True) response = "Доступные магазины для обслуживания:\n" castle_stage = sh[0].get("ownerCastle") if sh else '🖤' for shop in sh: castle, link, gold, mana, discount, name = shop.get("ownerCastle"), shop.get("link"), shop.get("maintenanceCost"), \ shop.get("mana"), shop.get("castleDiscount"), shop.get("name") if castle_stage != castle == player_castle: castle_stage = player_castle response += "\n" response += "{} <a href=\"https://t.me/share/url?url={}\">{}</a> 💰{} 💧{} {}" \ "\n".format(castle, "/ws_" + link, "/ws_" + link, gold, mana, "🏰: -{}%".format(discount) if discount is not None else "") bot.send_message(chat_id=mes.chat_id, text=response, parse_mode='HTML')
def resource_return(bot, job): cursor = conn.cursor() if job.context[1].get("status") not in ["sawmill", "quarry"]: logging.warning( "Status not in [\"sawmill\", \"quarry\"], status = {}".format( job.context[1].get("status"))) return statuses_to_res = {"sawmill": "wood", "quarry": "stone"} res = statuses_to_res.get(job.context[1].get("status")) count = 1 throne = Location.get_location(2) throne.treasury.change_resource(res, count) player = Player.get_player(job.context[0]) player.reputation += 3 player.update_to_database() job.context[1].update({"status": "castle_gates"}) buttons = get_general_buttons(job.context[1], player) if job.context[0] in construction_jobs: try: construction_jobs.pop(job.context[0]) except Exception: logging.error(traceback.format_exc()) request = "insert into castle_logs(player_id, action, result, additional_info, date) values (%s, %s, %s, %s, %s)" cursor.execute( request, (player.id, "collect_resources", 1, json.dumps({ "resource": res, "count": count }), datetime.datetime.now(tz=moscow_tz).replace(tzinfo=None))) bot.send_message(chat_id=job.context[0], text="Вы успешно добыли {}. Казна обновлена. Получено 3 🔘" "".format("дерево" if res == "wood" else "камень"), reply_markup=buttons) on_resource_return(player, res)
def adding_general(bot, update, user_data): """ Добавление Генерала """ mes = update.message try: player_id = int(mes.text) except ValueError: bot.send_message(chat_id=update.message.from_user.id, text="Неверный синтаксис.") return if player_id in high_access_list: bot.send_message(chat_id=update.message.from_user.id, text="Этот человек уже являетсяс генералом.") return player = Player.get_player(player_id, notify_on_error=False) if player is None: bot.send_message(chat_id=update.message.from_user.id, text="Невозможно найти этого холопа. " "Убедитесь, что он зарегистрирован в боте") return throne = Location.get_location(2) mid_players = throne.special_info.get("mid_players") mid_players.append(player_id) throne.update_location_to_database() fill_mid_players() bot.send_message(chat_id=update.message.from_user.id, text="@{} теперь генерал!".format(player.username)) user_data.update({"status": "king_cabinet"})
def on_grant_additional_operational(self, body): """ Метод, который вызывается при получении ответа о подтверждении кодом дополнительной операции :param body: dict - Message body """ accesses = {"GetGearInfo": "gear", "TradeTerminal": "wtb"} try: payload = body.get("payload") player_id = payload.get("userId") request_id = payload.get("requestId") player = Player.get_player(player_id, notify_on_error=False, new_cursor=self.cursor) if "requestId" in player.api_info and player.api_info.get( "requestId") == request_id: player.api_info.pop("requestId") player.update() if body.get("result") != "Ok": logging.error( "error while granting additional operation, {}".format( body)) return access = player.api_info.get("access") if access is None: access = [] player.api_info.update({"access": access}) operation = accesses.get(player.api_info.get("operation")) if operation not in access: access.append(operation) player.api_info.pop("operation") player.update() self.bot.send_message(chat_id=player_id, text="Действие API успешно разрешено.") except Exception: logging.error(traceback.format_exc())
def __on_message(self, body, message): """ Метод, который вызывается при получения сообщения ИЗ ПРИВАТНОЙ ОЧЕРЕДИ (не kafka!) :param body: dict - Message body :param message: Message - Message itself """ self.got_responses += 1 # print("Got {}".format(body)) message.ack() result = body.get("result") if result == 'InvalidToken': cursor = self.conn.cursor() request = "select id from players where (api_info ->> 'token')::text = %s::text" cursor.execute(request, (body.get("payload").get("token"), )) player_id = cursor.fetchone() if player_id is not None: player_id = player_id[0] player = Player.get_player(player_id) try: player.api_info.pop("token") player.api_info.pop("access") except KeyError: pass player.update() callback = self.callbacks.get(body.get("action")) if callback is None: logging.warning("Callback is None for {}".format(body)) return callback(body)
def remove_general(bot, update): """ Функция удаления Генерала """ mes = update.message player_id = re.search("_(\\d+)", mes.text) if player_id is None: bot.send_message(chat_id=update.message.from_user.id, text="Неверный синтаксис.") return player_id = int(player_id.group(1)) if player_id not in high_access_list: bot.send_message(chat_id=update.message.from_user.id, text="Так он, это, вроде и не генерал вовсе. " "Может, помилуем?") return player = Player.get_player(player_id, notify_on_error=False) throne = Location.get_location(2) mid_players = throne.special_info.get("mid_players") mid_players.remove(player_id) throne.update_location_to_database() fill_mid_players() bot.send_message(chat_id=update.message.from_user.id, text="@{} сослан в тортугу и больше не генерал".format( player.username))
def top_stat(bot, update): """ Функция, показывающая топы по выбранной категории (атака, стройка) """ mes = update.message player = Player.get_player(mes.from_user.id) text_to_stats = { "⚔️Атака": "attack", "⚔️Attack": "attack", "🛡Защита": "defense", "🛡Defence": "defense", "🔥Опыт": "exp", "🔥Experience": "exp", "🌲Дерево": "wood", "🌲Wood": "wood", "⛰Камень": "stone", "⛰Stone": "stone", "🏚Стройка": "construction", "🏚Construction": "construction" } stat = text_to_stats.get(mes.text) response = get_tops_text(player, stat, mes.text[0]) buttons = get_tops_buttons(stat) bot.send_message(chat_id=update.message.chat_id, text=response, parse_mode='HTML', reply_markup=buttons)
def update_daily_quests(bot, job): cursor = conn.cursor() request = "select id from players" cursor.execute(request) row = cursor.fetchone() while row is not None: player = Player.get_player(row[0]) if player is None: continue daily_quests: [Quest] = player.quests_info.get("daily_quests") if daily_quests is None: daily_quests = [] player.quests_info.update({"daily_quests": daily_quests}) else: daily_quests.clear() forbidden_list = [] for i in range(3): quest = copy.deepcopy(random.choice(list(quests.values()))) limit = 0 while (quest.id in forbidden_list or quest.skip_selection) and limit < 5: quest = copy.deepcopy(random.choice(list(quests.values()))) limit += 1 quest.start(player) if quest.daily_unique: forbidden_list.append(quest.id) daily_quests.append(quest) player.update_to_database() row = cursor.fetchone() time.sleep(1) plan_update_daily_quests()
def on_grant_token(self, body): """ Метод, который вызывается при получении ответа на отправленный код авторизации АПИ :param body: dict - Message body """ print("in callback", body) if body.get("result") != "Ok": logging.error("error while creating auth code, {}".format(body)) return payload = body.get("payload") player_id = payload.get("userId") token = payload.get("token") in_game_id = payload.get("id") player = Player.get_player(player_id, notify_on_error=False, new_cursor=self.cursor) if not all([player, token, player_id]): logging.error("Value is None: {} {} {}".format( player, token, player_id)) return if player.api_info is None: player.api_info = {} player.api_info.update({"token": token, "in_game_id": in_game_id}) player.update() self.bot.send_message( chat_id=player_id, text= "API успешно подключено.\nДля возможности обновления информации о снаряжении, " "пожалуйста, Пришлите форвард сообщения, полученного от @ChatWarsBot." ) self.auth_additional_operation(player_id, "GetGearInfo")
def request_roulette_bet(bot, update, user_data): """ Запрос ставки в рулетке """ mes = update.message user_data.update({"status": "awaiting_roulette_bet"}) roulette = Location.get_location(10) placed = roulette.special_info["placed"].get(str(mes.from_user.id)) if placed is None: placed = 0 buttons = get_general_buttons(user_data) player = Player.get_player(mes.from_user.id) if player is None: return bot.send_message( chat_id=update.message.from_user.id, text= "Введите количество 🔘жетонов для ставки:\nМинимальная ставка: 10🔘\n\n" "Ваша ставка: <b>{}</b>🔘.\n" "Доступно: <b>{}</b>🔘.{}\n\n<em>Обратите внимание, отменить ставку невозможно.</em>" "".format( placed, player.reputation, "\nМаксимальная ставка: <b>{}</b>🔘".format(ROULETTE_MAX_BET_LIMIT) if datetime.datetime.now(tz=moscow_tz).replace(tzinfo=None).time() < datetime.time(hour=ROULETTE_HOUR_LIMIT) else ""), reply_markup=buttons, parse_mode='HTML')
def grant_additional_operation(self, user_id, request_id, auth_code, player=None): """ Метод отправки кода доступа к дополнительной операции :param user_id: int - Player.id :param request_id: str - Request id (from auth_additional_operation) :param auth_code: str - Authentication code :param player: optional | Player instance (to avoid database request) """ if player is None: player = Player.get_player(user_id, notify_on_error=False) if player is None: raise RuntimeError token = player.api_info.get("token") if token is None: raise RuntimeError payload = {"requestId": request_id, "authCode": "{}".format(auth_code)} self.publish_message({ "token": token, "action": "grantAdditionalOperation", "payload": payload })
def new_roulette_top(bot, update): """ Обработчик нажатий на инлайн кнопки в топах рулетки """ stats = { "roulette_won": "🔘", "roulette_games_won": "🏆", "roulette_games_played": "🎰" } data, mes = update.callback_query.data, update.callback_query.message new_stat = "roulette_" + data.partition("roulette_top_")[2] player = Player.get_player(update.callback_query.from_user.id) new_text, new_buttons = get_tops_text(player=player, stat=new_stat, stat_text=stats.get(new_stat)), \ get_roulette_tops_buttons(curr=new_stat) if new_text != mes.text or new_buttons != mes.reply_markup: try: bot.editMessageText(chat_id=mes.chat_id, message_id=mes.message_id, text=new_text, reply_markup=new_buttons, parse_mode='HTML') # except Exception: # logging.error(traceback.format_exc()) except BadRequest: pass except TelegramError: pass bot.answerCallbackQuery(callback_query_id=update.callback_query.id)