Пример #1
0
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)
Пример #2
0
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})))
Пример #3
0
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')
Пример #4
0
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]})
Пример #5
0
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)
Пример #6
0
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)
Пример #7
0
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')
Пример #8
0
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')
Пример #9
0
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
Пример #10
0
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
Пример #11
0
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)
Пример #12
0
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})))
Пример #13
0
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
Пример #14
0
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)
Пример #15
0
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"])
Пример #16
0
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')
Пример #17
0
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")
Пример #18
0
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="Готово!")
Пример #19
0
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')
Пример #20
0
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)
Пример #21
0
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"})
Пример #22
0
 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())
Пример #23
0
    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)
Пример #24
0
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))
Пример #25
0
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)
Пример #26
0
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()
Пример #27
0
 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")
Пример #28
0
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')
Пример #29
0
    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
        })
Пример #30
0
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)