Пример #1
0
def top_notify(bot, job):
    cursor = conn.cursor()
    for guild_id in Guild.guild_ids:
        guild = Guild.get_guild(guild_id=guild_id)
        if guild is None or guild.division == "Луки" or not guild.members:  # or guild.tag != 'СКИ':
            continue
        response = get_top_text(guild,
                                3,
                                curr_cursor=cursor,
                                max_players=MAX_TOP_PLAYERS_SHOW)
        if guild.settings is None or guild.settings.get("tops_notify") in [
                None, True
        ]:
            for text in response:
                bot.send_message(chat_id=guild.chat_id,
                                 text=text,
                                 parse_mode='HTML')

    total_battles = count_battles_in_this_week()
    if total_battles >= 21:
        # Рассылка еженедельного топа
        for guild_id in Guild.guild_ids:
            guild = Guild.get_guild(guild_id=guild_id)
            if guild is None or guild.division == "Луки" or not guild.members:  # or guild.tag != 'СКИ':
                continue
            response = get_top_text(guild,
                                    21,
                                    curr_cursor=cursor,
                                    max_players=MAX_TOP_PLAYERS_SHOW_WEEK)
            if guild.settings is None or guild.settings.get("tops_notify") in [
                    None, True
            ]:
                for text in response:
                    bot.send_message(chat_id=guild.chat_id,
                                     text=text,
                                     parse_mode='HTML')

    time.sleep(1)
    plan_top_notify()
Пример #2
0
    def check_and_send_results(cls):
        if cls.has_hq and cls.has_locations:
            for alliance in Alliance.get_all_alliances():
                if alliance.hq_chat_id is not None:
                    dispatcher.bot.send_message(
                        chat_id=alliance.hq_chat_id,
                        parse_mode='HTML',
                        text=AllianceResults.
                        add_flag_to_old_alliance_locations(
                            alliance.add_flag_to_name(cls.get_text()),
                            alliance.id),
                        disable_web_page_preview=True)
                    top_str = cls.alliance_tops.get(alliance.name)
                    if top_str:
                        dispatcher.bot.send_message(
                            chat_id=alliance.hq_chat_id,
                            parse_mode='HTML',
                            text=top_str)

            for guild in Guild.get_all_guilds():
                if guild.settings is not None and guild.settings.get(
                        "alliance_results", False):
                    alliance = Alliance.get_alliance(
                        guild.alliance_id
                    ) if guild.alliance_id is not None else None
                    text_to_send = alliance.add_flag_to_name(cls.get_text(), locations=True) if alliance is not None \
                        else cls.get_text()
                    dispatcher.bot.send_message(chat_id=guild.chat_id,
                                                text=text_to_send,
                                                parse_mode='HTML',
                                                disable_web_page_preview=True)

            for guild_tag, text in cls.guild_tops.items():
                guild = Guild.get_guild(guild_tag=guild_tag)
                if guild is not None:
                    dispatcher.bot.send_message(chat_id=guild.chat_id,
                                                text=text,
                                                parse_mode='HTML')
def guild_top_battles(bot, update):
    mes = update.message
    player = Player.get_player(mes.from_user.id)
    if player is None:
        return
    if 'academy' in mes.text:
        guild = Guild.get_academy()
    else:
        guild = Guild.get_guild(player.guild)
    if guild is None:
        bot.send_message(
            chat_id=update.message.chat_id,
            text='Гильдейские топы доступны только членам гильдий.')
        return
    if not guild.check_high_access(player.id):
        bot.send_message(
            chat_id=update.message.chat_id,
            text='Гильдейские топы доступны только командирам и замам гильдий.'
        )
        return
    response = get_top_text(guild, 3)
    for text in response:
        bot.send_message(chat_id=mes.chat_id, text=text, parse_mode='HTML')
Пример #4
0
def request_update_guild_stocks(bot, update):
    player = Player.get_player(update.message.from_user.id)
    guild = Guild.get_guild(player.guild)
    if not guild:
        bot.send_message(
            chat_id=update.message.chat_id,
            text="Вы не состоите в гильдии. Попросите командира добавить вас")
        return
    update_whole_guild_stocks(player, guild)
    bot.send_message(
        chat_id=update.message.chat_id,
        text=
        "Запрошено обновление стоков всех игроков в гильдии.\nЭто может занять некоторое время."
    )
Пример #5
0
def update_stock_for_fails(bot, job):
    """
    Если по какой-то причине ответ от API получен не был для определённых игроков, то выполняется повторный запрос
    """
    cursor = conn.cursor()
    request = "select id, api_info from players where api_info ->> 'token' is not null and (api_info ->> " \
              "'change_stock_send')::boolean is true"
    cursor.execute(request)
    row = cursor.fetchone()
    while row is not None:
        player = Player.get_player(row[0],
                                   notify_on_error=False,
                                   new_cursor=cursor)
        cwapi.update_stock(player.id, player=player)
        row = cursor.fetchone()

    request = "select guild_id from guilds where (api_info -> 'change_stock_send')::text::boolean is true"
    cursor.execute(request)
    rows = cursor.fetchall()
    count_all = 0
    for row in rows:
        guild = Guild.get_guild(guild_id=row[0])
        api_players = guild.api_info.get("api_players")
        # if len(api_players) > 0:  # Сомнительно, часто гильдии не обновляются из-за багов АПИ
        #     api_players.pop(0)
        if not api_players:
            # guild.api_info.clear()
            bot.send_message(
                chat_id=SUPER_ADMIN_ID,
                parse_mode='HTML',
                text=
                "Гильдию <b>{}</b> невозможно обновить - нет игроков с доступом к АПИ."
                "".format(guild.tag))
            continue
        player_id = api_players[0]
        cwapi.update_guild_info(player_id)
        logging.info("Requested {} update".format(guild.tag))
        count_all += 1
    if count_all > 0:
        bot.send_message(
            chat_id=SUPER_ADMIN_ID,
            parse_mode='HTML',
            text=
            "Повторно запрошено обновление <b>{}</b> гильдий, игроки с доступом к АПИ подвинуты"
            "".format(count_all))
    if len(rows) > 0:
        bot.send_message(chat_id=SUPER_ADMIN_ID,
                         text="Начата проверка доступа к АПИ у гильдий")
        check_guilds_api_access(bot, None)
def arena_notify(bot, job):
    cursor = conn.cursor()
    for guild_id in Guild.guild_ids:
        guild = Guild.get_guild(guild_id=guild_id)
        if guild is None or guild.division == "Луки":
            continue
        if guild.settings is None or guild.settings.get("arena_notify") in [
                None, True
        ]:
            bot.send_message(
                chat_id=guild.chat_id,
                text=
                "Через час обнуление арен и дневного лимита опыта за крафт.")
    time.sleep(1)
    plan_arena_notify()
Пример #7
0
def grassroots_update_stock(bot, job):
    """
    Запрос на обновление стока всех игроков, и гильдий
    """
    print("starting updating")
    change_send = job.context.get("change_send") or False
    cursor = conn.cursor()
    request = "select id, api_info from players where api_info ->> 'token' is not null"
    cursor.execute(request)
    row = cursor.fetchone()
    count = 0
    count_all = 0
    while row is not None:
        player = Player.get_player(row[0],
                                   notify_on_error=False,
                                   new_cursor=cursor)
        count_all += 1
        player.api_info.update({"change_stock_send": change_send})
        player.update()
        count += 1 if change_send else 0
        cwapi.update_stock(player.id, player=player)
        row = cursor.fetchone()
    bot.send_message(
        chat_id=SUPER_ADMIN_ID,
        text="Запрошено обновление {} стоков, установлено {} флагов для отправки"
        "".format(count_all, count))

    # Обновление стока гильдий
    request = "select guild_id from guilds where (api_info -> 'api_players') is not null and " \
              "json_array_length(api_info -> 'api_players') > 0"
    cursor.execute(request)
    rows = cursor.fetchall()
    count, count_all = 0, 0
    for row in rows:
        guild = Guild.get_guild(guild_id=row[0])
        player_id = guild.api_info.get("api_players")[0]
        cwapi.update_guild_info(player_id)
        logging.info("Requested {} update".format(guild.tag))
        count_all += 1
        if change_send:
            guild.api_info.update({"change_stock_send": True})
            guild.update_to_database(need_order_recashe=False)
            count += 1
    bot.send_message(
        chat_id=SUPER_ADMIN_ID,
        text=
        "Запрошено обновление {} гильдий, установлено {} флагов для отправки"
        "".format(count_all, count))
Пример #8
0
def vote(bot, update):
    mes = update.message
    player = Player.get_player(mes.from_user.id)
    if player is None:
        return
    if player.castle != '🖤':
        bot.send_message(chat_id=mes.chat_id, text="Голосование доступно только жителям 🖤Скалы!")
        return
    if player.guild is None and player.id not in ALLOWED_LIST:
        bot.send_message(chat_id=mes.chat_id, text="Голосование доступно только членам гильдий.")
        return
        pass
    if Guild.get_guild(player.guild).is_academy():
        bot.send_message(chat_id=mes.chat_id, text="Ученикам Академии запрещено голосовать.")
        return
    vote_id = re.search("_(\\d+)", mes.text)
    if vote_id is None:
        bot.send_message(chat_id=mes.chat_id, text="Неверный синтаксис.")
        return
    vote_id = int(vote_id.group(1))
    vote = Vote.get_vote(vote_id)
    if vote is None:
        bot.send_message(chat_id=mes.chat_id, text="Голосование не найдено.")
        return
    if player.last_updated < vote.started:
        bot.send_message(chat_id=mes.chat_id, text="Для принятия участия в этом голосовании необходимо обновить "
                                                   "профиль после его начала.")
        return
    try:
        if vote.classes is not None and vote.classes and (player.game_class is None or
                                                          vote.classes[classes_list.index(player.game_class)] is False):
            bot.send_message(chat_id=mes.chat_id, text="Голосование недоступно для вашего класса.\n\n<em>В случае, "
                                                       "если ваш класс указан неверно, его можно обновить, "
                                                       "прислав форвард ответа </em>@ChatWarsBot<em> на </em>/me",
                             parse_mode='HTML')
            try:
                bot.answerCallbackQuery(callback_query_id=update.callback_query.id)
            except Exception:
                pass
            return
    except Exception:
        logging.error(traceback.format_exc())
    choice = vote.get_choice(player.id)
    response = get_vote_text(vote, choice)
    buttons = get_vote_buttons(vote, choice)
    bot.send_message(chat_id=mes.chat_id, text=response, reply_markup=buttons, parse_mode='HTML')
Пример #9
0
def get_guild_equipment_text(guild: Guild, selected_place: int,
                             selected_tier: int) -> str:
    if selected_place is None and selected_tier is None:
        return "Выберите тир и слот экипировки."
    res = "🏷Гильдейская экипировка:\n"
    equipment: [Equipment] = guild.get_equipment()
    place = PLACES[selected_place] if selected_place is not None else None
    tier = int(TIERS[selected_tier][2:]) if selected_tier is not None else None
    suitable_eq = []
    for eq in equipment:
        if (place is None or place == eq.place) and (tier is None
                                                     or tier == eq.tier):
            suitable_eq.append(eq)
    suitable_eq.sort(key=lambda x: (x.get_clear_name(), x.tier))
    for eq in suitable_eq:
        res += eq.format(mode="guild")
    return res
Пример #10
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)
Пример #11
0
 def update_guild_info(self, player_id, player=None):
     """
     Метод запроса обновления гильдии игрока
     :param player_id: int - Player.id
     :param player: optional | Player instance (to avoid database request)
     """
     if player is None:
         player = Player.get_player(player_id, notify_on_error=False)
         if player is None:
             raise RuntimeError
     if player is None:
         raise RuntimeError
     token = player.api_info.get("token")
     if token is None:
         self.remove_player_from_guild_access(Guild.get_guild(player.guild),
                                              player)
         raise RuntimeError
     self.publish_message({"token": token, "action": "guildInfo"})
Пример #12
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)
Пример #13
0
def gs(bot, update, user_data):
    player = Player.get_player(update.message.from_user.id)
    guild = Guild.get_guild(player.guild)
    if guild is None:
        return
    parse = re.match("/gs_(\\w+)", update.message.text)
    if parse is None:
        if update.message.text == "/gs":
            return gs_craft(bot, update, player, guild, user_data)
        bot.send_message(chat_id=update.message.chat_id,
                         text="Неверный синтаксис")
        return
    code = parse.group(1)
    all_parts = False
    if code.startswith("ap"):
        code = code.partition("ap")[2]
        all_parts = True
    response = "<b>{}</b> у игроков {}:\n".format(get_item_name_by_code(code),
                                                  guild.format())
    if all_parts:
        eq = get_equipment_by_code(code)
        for pl in sorted(
                filter(
                    lambda cur_pl: eq.recipe_code in cur_pl.stock or eq.
                    part_code in cur_pl.stock, guild.get_members()),
                key=lambda cur_pl: cur_pl.stock.get(
                    eq.recipe_code, 0) + cur_pl.stock.get(eq.part_code, 0),
                reverse=True):
            response += "<code>{}</code> {}📄 {}🔩\n".format(
                pl.pure_nickname, pl.stock.get(eq.recipe_code, 0),
                pl.stock.get(eq.part_code, 0))
    else:
        from castle_files.bin.api import update_whole_guild_stocks
        update_whole_guild_stocks(player, guild)
        for pl in sorted(filter(lambda cur_pl: code in cur_pl.stock.keys(),
                                guild.get_members()),
                         key=lambda cur_pl: cur_pl.stock.get(code),
                         reverse=True):
            response += "<code>x{:<2}</code> {}\n".format(
                pl.stock.get(code), pl.pure_nickname)
    bot.send_message(chat_id=update.message.chat_id,
                     text=response,
                     parse_mode="HTML")
Пример #14
0
def check_guilds_api_access(bot=None, job=None):
    """
    Проверка наличия доступа к АПИ у зарегистрированных гильдий.
    Вызывается отложенно, выполняется в фоне.
    :param bot: Bot
    :param job: Job
    :return: None
    """
    if job is None:
        reset = False
    else:
        try:
            reset = job.context.get("reset") or False
        except Exception:
            reset = False
    cursor = conn.cursor()
    if reset:
        logging.info("Clearing data about players with guilds API access")
        request = "update guilds set api_info = (api_info::jsonb - 'api_players')"
        cursor.execute(request)
    logging.info("Checking API access for guilds")
    request = "select guild_id from guilds where (api_info -> 'api_players') is null or " \
              "(api_info -> 'api_players')::text = '[]'::text"
    cursor.execute(request)
    rows = cursor.fetchall()
    if not rows:
        logging.info("All guilds have data about players with API access")
        return
    for row in rows:
        guild = Guild.get_guild(guild_id=row[0])
        search_for_players_with_api_access(guild)
    logging.info("Information about players with API access requested")

    if job and job.context and job.context.get("reschedule"):
        SUNDAY_INDEX = 6
        plan_work_week(check_guilds_api_access,
                       SUNDAY_INDEX,
                       3,
                       context={
                           "reset": True,
                           "reschedule": True
                       })
Пример #15
0
def send_guilds_stats(bot, job):
    """
    Раз в неделю отправляет в штаб академки инфу о текущем составе гильдий
    """
    response = "Гильдии Скалы на {}:\n" \
               "<em>👥 - число игроков по боту, 👥(API) - число игроков в ги по АПИ, 🏅 - уровень гильдии</em>\n" \
               "".format(datetime.date.today().strftime("%d/%m/%y"))
    for guild_id in Guild.guild_ids:
        guild = Guild.get_guild(guild_id)
        if not guild.is_active():
            continue
        if guild.castle != "🖤":
            continue
        lvl, members = guild.api_info.get("lvl"), guild.api_info.get("members")
        response += "<b>{}</b> 👥{} {}\n".format(guild.tag, guild.members_count,
                                                "(API - {}) 🏅{}".format(members, lvl) if lvl else "")
    bot.send_message(chat_id=ACADEMY_HQ_CHAT_ID, text=response, parse_mode='HTML')

    time.sleep(1)
    plan_academy_guilds_stats_send()
Пример #16
0
def guild_equipment(bot, update, user_data):
    mes = update.callback_query.message
    data = update.callback_query.data
    pop_from_user_data_if_presented(
        user_data,
        ["guild_equipment_selected_place", "guild_equipment_selected_tier"])
    requested_player_id = update.callback_query.from_user.id
    guild_id = re.search("_(\\d+)", data)
    if guild_id is None:
        bot.send_message(chat_id=mes.chat_id,
                         text="Произошла ошибка. Начните сначала.")
        return
    guild_id = int(guild_id.group(1))
    guild = Guild.get_guild(guild_id)
    bot.send_message(chat_id=mes.chat_id,
                     text=get_guild_equipment_text(guild, None, None),
                     reply_markup=get_guild_equipment_buttons(
                         guild, None, None),
                     parse_mode='HTML')
    bot.answerCallbackQuery(update.callback_query.id)
Пример #17
0
def mail_and_pin(bot, update):
    mes = update.message
    text = mes.text.partition("mailing_pin")[2]
    for guild_id in Guild.guild_ids:
        guild = Guild.get_guild(guild_id=guild_id)
        if guild is None:
            continue
        if guild.division == "Луки" or not guild.mailing_enabled:
            continue
        try:
            message = bot.sync_send_message(chat_id=guild.chat_id,
                                            text=text,
                                            parse_mode='HTML')
            bot.pinChatMessage(chat_id=message.chat_id,
                               message_id=message.message_id)
        except TelegramError:
            pass
    bot.send_message(update.message.chat_id,
                     text="Успешно отправлено!",
                     reply_to_message_id=mes.message_id)
Пример #18
0
def ga_map(bot, update):
    mes = update.message
    locations = AllianceLocation.get_active_locations()
    res = "🗺 Карта альянсов:\n"
    player = Player.get_player(mes.from_user.id)
    guild = Guild.get_guild(player.guild)
    alliance = Alliance.get_alliance(guild.alliance_id) if guild is not None else None
    location_to_text: {AllianceLocation: str} = []
    for location in locations:
        text = location.format_link_view(alliance)
        alli_name = Alliance.get_alliance(location.owner_id).name if location.owner_id is not None else "Пустует!"
        text += "   ╰🎪{} {}\n".format(alli_name, location.turns_owned)
        location_to_text.append([location, text])

    res += sort_and_add_types_to_location_list(location_to_text)

    alliance = Alliance.get_player_alliance(Player.get_player(mes.from_user.id))
    if alliance is not None:
        res = alliance.add_flag_to_name(res)
    bot.send_message(chat_id=mes.chat_id, text=res, parse_mode='HTML')
Пример #19
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)
Пример #20
0
 def send_guild_changes_to_mid(self):
     """
     Метод, который отправляет сообщение с изменениями гп у гильдий в мид (после каждой битвы)
     """
     guild_changes = {
         k: v
         for k, v in sorted(list(self.guild_changes.items()),
                            key=lambda x: x[1],
                            reverse=True)
     }
     logging.error(guild_changes)
     self.guild_changes_work = None
     self.guild_changes.clear()
     response = "Изменения глори по гильдиям:\n"
     for tag, glory_change in list(guild_changes.items()):
         guild = Guild.get_guild(guild_tag=tag, new_cursor=True)
         response += "{}<b>{}</b> 🎖:<code>{:>3}</code>\n".format(
             guild.castle, guild.tag, glory_change)
     self.bot.send_message(chat_id=MID_CHAT_ID,
                           text=response,
                           parse_mode='HTML')
Пример #21
0
def update_alliance(bot, update):
    mes = update.message
    forward_message_date = get_message_forward_time(mes)
    if datetime.datetime.now() - forward_message_date > datetime.timedelta(seconds=30):
        bot.send_message(chat_id=mes.chat_id, text="Это устаревший альянс.", reply_to_message_id=mes.message_id)
        return
    name = re.search("🤝(.+?) ?\n", mes.text).group(1)
    if name not in ALLOWED_LIST:
        return
    alliance = Alliance.get_or_create_alliance_by_name(name)
    owner = re.search("Owner:.*\\[(.+)\\](.*)", mes.text)
    owner_tag = owner.group(1)
    guild = Guild.get_guild(guild_tag=owner_tag)
    player = Player.get_player(mes.from_user.id)
    if guild is not None and guild.id == player.guild:
        guild.alliance_id = alliance.id
        guild.update_to_database()
        alliance.creator_id = guild.commander_id
        alliance.update()
        bot.send_message(chat_id=mes.chat_id,
                         text="Информация об альянсе и гильдии обновлена. Теперь пришли мне 📋 Roster!")
Пример #22
0
def get_craft_text_withdraw_and_buy_by_code(code: str,
                                            count,
                                            player_id,
                                            explicit: bool = True) -> tuple:
    name = get_craft_name_by_code(code)
    craft_eq = get_craft_by_name(name)
    player = Player.get_player(player_id)
    guild = Guild.get_guild(player.guild)
    guild_stock = guild.get_stock({}).copy()
    withdraw, buy, to_craft = {}, {}, {}
    res = get_craft_text(craft_eq,
                         name,
                         code,
                         count,
                         player.stock.copy(),
                         guild_stock,
                         withdraw,
                         buy,
                         to_craft,
                         explicit=explicit)
    return res, withdraw, buy, to_craft
Пример #23
0
def change_guild_equipment_param(bot, update, user_data):
    mes = update.callback_query.message
    data = update.callback_query.data
    parse = re.search("guild_equipment_(\\w+)_(\\d+)_(\\d+)", data)
    if parse is None:
        bot.send_message(chat_id=mes.chat_id,
                         text="Произошла ошибка. Начните сначала.")
        return
    param, guild_id, value = parse.group(1), int(parse.group(2)), int(
        parse.group(3))
    guild = Guild.get_guild(guild_id)
    if guild is None:
        bot.send_message(chat_id=mes.chat_id,
                         text="Гильдия не найдена. Начните сначала.")
        return
    param_string = "guild_equipment_selected_{}".format(param)
    cur_value = user_data.get(param_string)
    if value == cur_value:
        pop_from_user_data_if_presented(user_data, param_string)
    else:
        user_data.update({param_string: value})
    place, tier = user_data.get(
        "guild_equipment_selected_place"), user_data.get(
            "guild_equipment_selected_tier")
    try:
        bot.editMessageText(chat_id=mes.chat_id,
                            message_id=mes.message_id,
                            text=get_guild_equipment_text(guild, place, tier),
                            reply_markup=get_guild_equipment_buttons(
                                guild, place, tier),
                            parse_mode='HTML')
    # except Exception:
    # logging.error(traceback.format_exc())
    except BadRequest:
        logging.error(traceback.format_exc())
    except TelegramError:
        pass
    bot.answerCallbackQuery(callback_query_id=update.callback_query.id)
Пример #24
0
def reward_g_def(player, reward, cost, *args, **kwargs):
    guild = Guild.get_guild(player.guild)
    if guild is None:
        dispatcher.bot.send_message(
            player.id,
            text="Гильдия не найдена. Вы должны состоять в гильдии. "
            "Жетоны возвращены.")
        player.reputation += cost
        player.update()
        return
    do_mailing(
        dispatcher.bot,
        "📣📣📣Вы слышите звуки рога! Это {} зазывает сынов и дочерей Скалы на защиту!\n"
        "/g_def {}".format(guild.tag, guild.tag))
    dispatcher.bot.send_message(
        chat_id=STATUSES_MODERATION_CHAT_ID,
        text="Не забудьте снять жетоны тем, "
        "кого не будет в дефе <b>{}</b> в ближайшую битву!".format(guild.tag),
        parse_mode='HTML')
    job.run_once(when=get_time_remaining_to_battle() +
                 datetime.timedelta(minutes=5),
                 callback=g_def_remind_after_battle,
                 context={"tag": guild.tag})
Пример #25
0
def get_chat_helpers(chat_id: int, minus, plus, avg_lvl: float, player: Player) -> ['Player']:
    if chat_id is None:
        return []
    barracks = Location.get_location(1)
    try:
        ping_list = barracks.special_info.get("mobs_notify").get(str(chat_id)).copy()
    except Exception:
        ping_list = None
    if not ping_list:
        ping_list = []
    ping_list = set(ping_list)
    if player.guild is not None or ping_list:
        guild = Guild.get_guild(guild_id=player.guild)
        if guild.is_academy() and chat_id == guild.chat_id:
            # Пинги для академки отключены
            return
        if guild is not None and guild.chat_id == chat_id:
            ping_list.update(guild.members)
    ping_list.discard(player.id)
    ping_list = list(filter(lambda player: avg_lvl - minus <= player.lvl <= avg_lvl + plus,
                            map(lambda player_id: Player.get_player(player_id), list(ping_list))))
    ping_list.sort(key=lambda player: player.hp if player.hp is not None else -1, reverse=True)
    return ping_list
Пример #26
0
def request_kabala(bot, update):
    """
    Сбрасывает инфу о кабале у всех игроков, рассылает всем предложение взять кредит.
    """
    if update.message.from_user.id != SUPER_ADMIN_ID:
        return
    text = """Уважаемый/ая воен/мастер (нужное подчеркнуть)!
Астрологи объявили неделю хаоса!
Чайная Лига предварительно одобрила вам кредит на 10000 Жетонов!
ДА ЗДРАВСТВУЕТ СТИКЕРНО-ТРИГЕРННО-РАССЫЛОЧНЫЙ АД!
Для одобрения нажмите /kabala""".format(KABALA_GAIN)
    count = 0
    for guild_id in Guild.guild_ids:
        guild = Guild.get_guild(guild_id)
        if guild is not None:
            for player_id in guild.members:
                user_data = dispatcher.user_data.get(player_id)
                if 'kabala_time' in user_data:
                    user_data.pop('kabala_time')
                bot.send_message(chat_id=player_id, text=text)
                count += 1
    bot.send_message(
        chat_id=SUPER_ADMIN_ID,
        text="Предлложение о кредите разослано {} игрокам".format(count))
Пример #27
0
def alliance_roster(bot, update):
    alliance = Alliance.get_player_alliance(Player.get_player(update.message.from_user.id))
    if alliance is None:
        bot.send_message(chat_id=update.message.chat_id,
                         text="Вы не состоите в альянсе. Пусть создатель альянса отправил ответ чв на 🤝Альянс, "
                              "а затем - 📋 Roster")
        return
    forward_message_date = get_message_forward_time(update.message)
    if datetime.datetime.now() - forward_message_date > datetime.timedelta(seconds=30):
        bot.send_message(chat_id=update.message.chat_id, text="Это устаревший состав.",
                         reply_to_message_id=update.message.message_id)
        return
    tags = re.findall("\\[(\\w+)\\]", update.message.text)
    for guild_tag in tags:
        guild = Guild.get_guild(guild_tag=guild_tag)
        if guild is None:
            continue
        guild.alliance_id = alliance.id
        guild.update_to_database()
    bot.send_message(chat_id=update.message.chat_id,
                     text="Состав альянса обновлён.\n"
                          "Установите чат МИДа альянса командой /set_alliance_hq_chat {chat_id}\n"
                          "<em>chat_id можно получить при помощи команды /chat_info в нужном чате.</em>",
                     parse_mode='HTML')
Пример #28
0
def get_craft_text_withdraw_and_buy_by_code(code: str,
                                            count,
                                            player_id,
                                            explicit: bool = True,
                                            depth_limit: int = None) -> tuple:
    name = get_craft_name_by_code(code)
    craft_eq = get_craft_by_name(name)
    player = Player.get_player(player_id)
    guild = Guild.get_guild(player.guild)
    guild_stock = guild.get_stock({}).copy() if guild is not None else {}
    player_stock = player.stock.copy() if player is not None else {}
    withdraw, buy, to_craft = {}, {}, {}
    res = get_craft_text(craft_eq,
                         name,
                         code,
                         count,
                         player_stock,
                         guild_stock,
                         withdraw,
                         buy,
                         to_craft,
                         explicit=explicit,
                         depth_limit=depth_limit)  # Has side-effects!
    return res, withdraw, buy, to_craft
Пример #29
0
def gs_craft_button_click(bot, update, user_data):
    tier = user_data.get("gs_tier")
    parse = re.search("_(\\d+)", update.callback_query.data)
    if parse is None:
        bot.answerCallbackQuery(update.callback_query.id,
                                text="Произошла ошибка.")
        return
    new_tier = int(parse.group(1))
    if new_tier == tier:
        new_tier = None
        user_data.pop("gs_tier")
    else:
        user_data.update({"gs_tier": new_tier})
    response = get_gs_craft_text(
        Guild.get_guild(
            Player.get_player(update.callback_query.from_user.id).guild),
        new_tier)
    bot.editMessageText(chat_id=update.callback_query.message.chat_id,
                        message_id=update.callback_query.message.message_id,
                        text=response,
                        parse_mode='HTML',
                        reply_markup=InlineKeyboardMarkup(
                            get_gs_buttons(new_tier)))
    bot.answerCallbackQuery(update.callback_query.id)
Пример #30
0
    def on_guild_info(self, body):
        """
        Метод, который вызывается при получении информации о гильдии (в том числе и её стока)
        :param body: dict - Message body
        """
        try:
            payload = body.get("payload")
            if payload is None:
                logger.debug("Payload is None in guild info: {}".format(body))
                return
            player_id = payload.get("userId")
            player = Player.get_player(player_id, notify_on_error=False)
            guild = Guild.get_guild(player.guild)
            if body.get("result") != "Ok":
                logging.error(
                    "error while requesting guild info, {}".format(body))
                if body.get("result") == "Forbidden":
                    try:
                        self.remove_player_from_guild_access(guild, player)
                    except ValueError:
                        pass
                    except Exception:
                        logging.error(
                            "Can not remove guild api access: {}".format(
                                traceback.format_exc()))
                return
            # print(body)
            # print(json.dumps(body, sort_keys=1, indent=4, ensure_ascii=False))
            name, glory, lvl, members, stock_size, stock_limit, \
                tag, castle = payload.get("name"), payload.get("glory"), payload.get("level"), \
                payload.get("members"),  payload.get("stockSize"), payload.get("stockLimit"), \
                payload.get("tag"), payload.get("castle")
            got_stock = payload.get("stock")
            codes = payload.get("itemCodes")
            stock, equipment_temp, equipment = {}, {}, []
            for i_name, count in list(got_stock.items()):
                code = get_item_code_by_name(i_name)
                eq = get_equipment_by_name(i_name)
                if eq is not None:
                    lst = equipment_temp.get(eq.name)
                    if lst is None:
                        lst = []
                        equipment_temp.update({eq.name: lst})
                    for i in range(count):
                        lst.append(copy.deepcopy(eq))
                stock.update({code or i_name: count})
            stock = {
                k: stock[k]
                for k in sorted(stock, key=stock_sort_comparator)
            }
            self.__set_guild_equipment_codes(codes, equipment_temp, equipment)
            player = Player.get_player(player_id, notify_on_error=False)
            if player is None or player.guild is None:
                logging.warning(
                    "Received guild info, but player is None (or guild) for id {}"
                    .format(player_id))
                return
            if guild is None or guild.tag != tag:
                logging.warning(
                    "Received guild info, but guild is None or not euqal for"
                    " {} (@{})".format(player.nickname, player.username))
                return
            old_stock, old_glory, change_send = guild.api_info.get("stock") or {}, guild.api_info.get("glory") or 0, \
                                                guild.api_info.get("change_stock_send") or False
            if change_send:
                self.guild_changes.update({guild.tag: glory - old_glory})
                if self.guild_changes_work is None:
                    self.guild_changes_work = threading.Timer(
                        60, self.send_guild_changes_to_mid)
                    self.guild_changes_work.start()
                response = "Итоги битвы {}<b>{}</b>\n".format(
                    guild.castle, guild.tag)
                response += "<b>🎖Glory:</b> <code>{}</code>\n\n".format(
                    glory - old_glory)
                response += self.get_stock_change_text(old_stock, stock)
                attack, defense, exp, gold, total_stock = guild.count_battle_stats(
                )
                response += "\nПредыдущая битва:\n<code>Атака: {:>5}⚔\nЗащита:{:>5}🛡\nОпыт: {:>6}🔥\nЗолото:{:>5}💰\n" \
                            "Сток:  {:>5}📦</code>\n".format(attack, defense, exp, gold, total_stock)
                self.bot.send_message(chat_id=guild.chat_id,
                                      text=response,
                                      parse_mode='HTML')
                guild.api_info.pop("change_stock_send")
                guild.update_to_database(need_order_recashe=False)

            guild.name = name
            api_players = guild.api_info.get("api_players")
            if api_players is None:
                api_players = []
                guild.api_info.update({"api_players": api_players})
            if player_id not in api_players:
                api_players.append(player_id)
            guild.api_info.update({
                "stock": stock,
                "glory": glory,
                "lvl": lvl,
                "members": members,
                "stock_size": stock_size,
                "stock_limit": stock_limit,
                "equipment": equipment
            })
            guild.castle = castle
            guild.last_updated = datetime.datetime.now(tz=moscow_tz).replace(
                tzinfo=None)
            guild.update_to_database(need_order_recashe=False)
        except Exception:
            logging.error(traceback.format_exc())