def rangers_notify_start(bot, update):
    cursor = conn.cursor()
    time_to_battle = get_time_remaining_to_battle()
    print("time_to_battle", time_to_battle)
    try:
        callback_chat_id = update.message.chat_id
    except AttributeError:
        try:
            callback_chat_id = int(update)
        except TypeError:
            return
    count = 0
    request = "select id from players where class_skill_lvl is not NULL"
    cursor.execute(request)
    row = cursor.fetchone()
    while row is not None:
        player = Player.get_player(row[0])
        if player is None:
            row = cursor.fetchone()
            continue
        if player.settings is not None and player.settings.get(
                "rangers_notify") is False:
            row = cursor.fetchone()
            continue
        guild = Guild.get_guild(guild_id=player.guild)
        if guild is None:
            row = cursor.fetchone()
            continue
        telegram_username = player.username
        username = player.nickname
        class_skill_lvl = player.class_skill_lvl
        context = [telegram_username, username, guild.chat_id]
        print(class_skill_lvl)
        time_to_aim_mins = ranger_aiming_minutes[class_skill_lvl] if \
            class_skill_lvl < len(ranger_aiming_minutes) else 40

        time_to_aim = datetime.timedelta(minutes=time_to_aim_mins)
        print("time_to_aim", time_to_aim)
        time_to_notify = time_to_battle - time_to_aim - datetime.timedelta(
            minutes=1)
        print(time_to_notify)
        # time_to_notify = datetime.timedelta(minutes=1)    # TEST
        if time_to_notify >= datetime.timedelta(minutes=0):
            job.run_once(ranger_notify, time_to_notify, context=context)

        row = cursor.fetchone()
        count += 1
    cursor.close()
    bot.send_message(
        chat_id=callback_chat_id,
        text="Запланировано оповещение <b>{0}</b> бедных лучников".format(
            count),
        parse_mode='HTML')
Ejemplo n.º 2
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})
Ejemplo n.º 3
0
def plan_clear_alliance_results(*args):
    job.run_once(clear_results, get_time_remaining_to_battle())
def notify_guild_attack(bot, update):
    mes = update.message
    remaining_time = get_time_remaining_to_battle()
    forward_message_date = utc.localize(
        mes.forward_date).astimezone(tz=moscow_tz).replace(tzinfo=None)
    if forward_message_date - datetime.datetime.now() > datetime.timedelta(
            minutes=2):
        return 0
    if remaining_time > datetime.timedelta(minutes=30):
        pass
        return 0
    ready_to_battle = mes.text.count("[⚔]") + mes.text.count("[🛡]")
    sleeping = mes.text.count("[🛌]") + mes.text.count("[⚒]")
    response = "<b>{0}</b>\nГотово к битве: <b>{1}</b>\nНе готово к битве, но занято <b>{2}</b>\n" \
               "Спит: <b>{3}</b>\n\nВремя до битвы: {4}\n".format(mes.text.splitlines()[0], ready_to_battle,
                                                                  mes.text.count("\n") - ready_to_battle - sleeping,
                                                                  sleeping, ":".join(str(remaining_time).partition(".")[0].split(":")[0:3]))
    request = "select guild_id from guilds where chat_id = %s"
    cursor.execute(request, (mes.chat_id, ))
    row = cursor.fetchone()
    if row is None:
        return
    guild = Guild.get_guild(guild_id=row[0])
    set = guild.settings.get(
        "battle_notify") if guild.settings is not None else True
    if guild is None or set is False:
        return
    if mes.chat_id != guild.chat_id:
        return
    if mes.from_user.id not in get_admin_ids(
            bot, chat_id=mes.chat_id) and not check_access(mes.from_user.id):
        bot.send_message(chat_id=mes.chat_id,
                         text="Доступ только у админов",
                         parse_mode='HTML',
                         reply_to_message_id=mes.message_id)
        return
    do_not_ready = []
    sleeping = []
    for string in mes.text.splitlines()[1:]:
        if not ("[⚔]" in string or "[🛡]" in string):
            nickname = string.partition("]")[2][1:]
            do_not_ready.append(nickname)
            if "[🛌]" in string or "[⚒]" in string:
                sleeping.append(nickname)

    in_dict_do_not_ready = []
    in_dict_sleeping = []
    ping_dict = {
        "do not ready": in_dict_do_not_ready,
        "sleeping": in_dict_sleeping
    }
    for player_id in guild.members:
        player = Player.get_player(player_id, notify_on_error=False)
        if player is None:
            continue
        db_nickname = player.nickname.partition("]")[2]
        if db_nickname in do_not_ready:
            in_dict_do_not_ready.append(player.username)
            if db_nickname in sleeping:
                in_dict_sleeping.append(player.username)

    ping_by_chat_id.update({mes.chat_id: ping_dict})
    response += "Пингануть тех, кто спит: /notify_guild_sleeping\n" \
                "Пингануть всех, кто не готов: /notify_guild_not_ready"
    bot.send_message(chat_id=mes.chat_id, text=response, parse_mode='HTML')
Ejemplo n.º 5
0
def players_update_monitor():
    """
    Выполняется на всём протяжении функционирования бота. Раз в секунду запрашивает обновление
    MAX_PLAYERS_AUTO_UPDATE_PER_SECOND профилей игроков, ранее всего обновлявших свои профили.
    Раз в GUILD_UPDATE_INTERVAL_SECONDS секунд вызывает обновление гильдии, которая не обновлялась дольше всего.
    :return: None
    """
    cursor = conn.cursor()
    time.sleep(7)

    check_guilds_api_access()
    logging.info("Started updating profiles")
    i = 0
    while True:
        try:
            i += 1
            if not cwapi.active:
                return 0
            time_to_battle = get_time_remaining_to_battle()
            if time_to_battle < datetime.timedelta(minutes=30) or \
                    time_to_battle > datetime.timedelta(minutes=30, hours=7):
                time.sleep(1)
                continue
            if i % GUILD_UPDATE_INTERVAL_SECONDS == 0:
                # Обновление гильдии
                request = "select guild_id from guilds order by last_updated nulls first"
                cursor.execute(request)
                rows = cursor.fetchall()
                guild, player_id = None, None
                for row in rows:
                    guild_id = row[0]
                    guild = Guild.get_guild(guild_id=guild_id)
                    player_id = get_player_with_api_access_from_guild(guild)
                    if player_id is not None:
                        break
                if guild is None or player_id is None:
                    logging.error("No guild to update")
                    continue
                cwapi.update_guild_info(player_id)
                guild.api_info.update()
                logging.debug("Updating {} through CW3 API".format(guild.tag))

            request = "select id from players where api_info -> 'token' is not null order by last_updated limit %s"
            cursor.execute(request, (MAX_PLAYERS_AUTO_UPDATE_PER_SECOND, ))
            row = cursor.fetchone()
            while row is not None:
                if row is None:
                    logging.error("Request is None in players_update_monitor")
                    return 0
                player = Player.get_player(row[0])
                cwapi.update_player(player.id, player=player)
                logging.debug("Updating {} through CW3 API".format(
                    player.nickname))
                if not cwapi.active:
                    return 0
                access = player.api_info.get("access")
                if access is not None and "gear" in access:
                    cwapi.update_gear(player.id, player=player)
                row = cursor.fetchone()
            time.sleep(1)
        except Exception:
            logging.error(traceback.format_exc())
 def actually_send_message(self, *args, **kwargs):
     chat_id = kwargs.get('chat_id')
     lock = self.counter_lock
     wait_start = time.time()
     try:
         with lock:
             while True:
                 if self.messages_per_second < MESSAGE_PER_SECOND_LIMIT:
                     self.messages_per_second += 1
                     # lock.release()
                     break
                 # logging.info("sleeping")
                 lock.wait()
                 # logging.info("woke up")
     finally:
         pass
     wait_end = time.time()
     advanced_callback.put({
         "chat_id": kwargs.get("chat_id"),
         "wait_start": wait_start,
         "wait_end": wait_end
     })
     message = None
     body = {"chat_id": chat_id, "time": time.time()}
     self.second_reset_queue.put(body)
     remaining_time = get_time_remaining_to_battle()
     timeout = 5
     if kwargs.get("timeout_retry"):
         try:
             kwargs.pop("timeout_retry")
             kwargs.pop("timeout")
         except Exception:
             pass
     elif remaining_time <= datetime.timedelta(seconds=15):
         kwargs.update({"timeout": 0.8, "timeout_retry": True})
         timeout = 0.8
     try:
         reply_markup = kwargs.get("reply_markup")
         if isinstance(reply_markup, ReplyMarkup):
             reply_markup = reply_markup.to_json()
         parse_mode = kwargs.get("parse_mode")
         data = {'chat_id': chat_id, 'text': kwargs["text"]}
         if reply_markup is not None:
             data.update({'reply_markup': reply_markup})
         if parse_mode is not None:
             data.update({'parse_mode': parse_mode})
         # try:
         #     resp = requests.post(self.base_url + '/sendMessage', data=json.dumps(data).encode('utf-8'),
         #                          headers={'Content-Type': 'application/json'}, timeout=timeout)
         # except Exception:
         #     raise TimedOut
         # resp = resp.json()
         # print(resp)
         # ok = resp["ok"]
         # if not ok:
         #     code, descr = resp["error_code"], resp["description"]
         #     errors = {400: BadRequest(descr), 403: Unauthorized(descr)}
         #     error = errors.get(code)
         #     if error is None:
         #         logging.error("Unknown error for code {}".format(code))
         #         raise BadRequest
         #     raise error
         # message = Message.de_json(resp["result"], super(AsyncBot, self))
         message = super(AsyncBot, self).send_message(*args, **kwargs)
     except TimedOut:
         logging.error("Order timeout")
         # time.sleep(0.1)
         # message = self.actually_send_message(*args, **kwargs)
         return TIMEOUT_ERROR_CODE
     except Unauthorized:
         return UNAUTHORIZED_ERROR_CODE
     except BadRequest:
         logging.error(traceback.format_exc())
         return BADREQUEST_ERROR_CODE
     except NetworkError:
         time.sleep(0.1)
         message = super(AsyncBot, self).send_message(*args, **kwargs)
     except Exception:
         logging.error(traceback.format_exc())
         return OTHER_ERROR_CODE
     return message