def reward_g_def(player, reward, cost, *args, **kwargs): guild = Guild.get_guild(player.guild) if guild is None or guild.castle != HOME_CASTLE: if guild is None: text = "Гильдия не найдена. Вы должны состоять в гильдии.\nЖетоны возвращены." else: text = "Функция доступна только для гильдий из Скалы.\nЖетоны возвращены." dispatcher.bot.send_message(player.id, text=text) player.reputation += cost player.update() raise RewardRollbackException 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})
def parse_stats(): data = castles_stats_queue.get() while data is not None: debug = data.get("debug", False) data = data.get("data") # logging.error("Got data in parse: {}".format(data)) if 'Результаты сражений:' in data: # Результаты битвы замков if not debug: response_all = "Игроки, попавшие в топ:\n" for guild_id in Guild.guild_ids: response = "" guild = Guild.get_guild(guild_id=guild_id) tag = guild.tag for castle_results_string in data.split("\n\n"): if tag in castle_results_string: try: attacked_castle = re.search( '[🍁☘🖤🐢🦇🌹🍆]', castle_results_string).group(0) except TypeError: attacked_castle = "???" nicknames_list = re.findall( ".\\[{}\\][^🍁☘🖤🐢🦇🌹🍆🎖\n]+".format(tag), castle_results_string) print(nicknames_list) for nickname in nicknames_list: if response == "": response = "Игроки, попавшие в топ:\n" response += "{}{} <b>{}</b>\n".format( "🛡️" if nickname[0] == attacked_castle else "⚔️", attacked_castle, nickname[:-1]) response_all += "{}{} <b>{}</b>\n".format( "🛡️" if nickname[0] == attacked_castle else "⚔️", attacked_castle, nickname[:-1]) if response != "": if guild.chat_id is None: continue dispatcher.bot.send_message(chat_id=guild.chat_id, text=response, parse_mode='HTML') if response_all != "Игроки, попавшие в топ:\n": dispatcher.bot.send_message(chat_id=CENTRAL_SQUARE_CHAT_ID, text=response_all, parse_mode='HTML') worldtop_strings = data.split("\n\n")[-1].splitlines() worldtop = load_worldtop(battle_id=count_battle_id() - 1) old_worldtop = copy.deepcopy(worldtop) for string in worldtop_strings: parse = re.search("(.).* \\+(\\d+) 🏆 очков", string) if parse is None: continue castle = parse.group(1) count = int(parse.group(2)) score = worldtop.get(castle) score += count worldtop.update({castle: score}) sort_worldtop(worldtop) logging.info("Worldtop updated: {}: {}".format(castle, count)) save_worldtop(worldtop) if not debug: send_worldtop_update(old_worldtop, worldtop) logging.info("Worldtop at the end: {}".format(worldtop)) elif data.startswith("🤝Headquarters news:") or data.startswith( "🗺State of map:"): # Итоги штабов альянсов logging.info("Got alliance news") parse_alliance_battle_results(data, debug) else: # Сообщение о пиратстве response_by_tags = {} data = data.replace("Attackers:", " 🗡Атакующие:") data = data.replace("Defenders:", " 🛡Обороняющиеся:") guild_list = re.split("[⚔🛡] ..?Гильдия", data) for guild_str in guild_list: new_str = guild_str new_str = "{}".format('⚔️' if 'атакована' in new_str else '🛡') + new_str tags = re.findall("[🍁☘🖤🐢🦇🌹🍆](\\w+)", guild_str) tags = list(set(tags)) for tag in tags: new_str = new_str.replace(tag, "<b>{}</b>".format(tag)) for tag in tags: lst = response_by_tags.get(tag) if lst is None: lst = "Итоги гильдейских битв с вашим участием:\n\n" response_by_tags.update({tag: lst}) lst += new_str + "\n" response_by_tags.update({tag: lst}) # dispatcher.bot.send_message(chat_id=SUPER_ADMIN_ID, text=guild_str, parse_mode='HTML') import json # logging.error("Guild list for parse_stats: {}".format(json.dumps(guild_list, indent=4, ensure_ascii=False))) logging.error("Response by tags: {}".format( json.dumps(response_by_tags, indent=4, ensure_ascii=False))) print(guild_list) print(json.dumps(response_by_tags, indent=4, ensure_ascii=False)) for tag, string in list(response_by_tags.items()): guild = Guild.get_guild(guild_tag=tag) if guild is None: continue dispatcher.bot.send_message(chat_id=guild.chat_id, text=string, parse_mode='HTML') data = castles_stats_queue.get()
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')
def mob(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) names, lvls, buffs = [], [], [] for string in mes.text.splitlines(): parse = re.search("(.+) lvl\\.(\\d+)", string) if parse is not None: name = parse.group(1) lvl = int(parse.group(2)) names.append(name) lvls.append(lvl) buffs.append("") else: parse = re.search(" ╰ (.+)", string) if parse is not None: buff = parse.group(1) buffs.pop() buffs.append(buff) 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) # forward_message_date = datetime.datetime.now(tz=moscow_tz).replace(tzinfo=None) - datetime.timedelta( # minutes=2, seconds=30) # Test only request = "insert into mobs(link, mob_names, mob_lvls, date_created, created_player, on_channel, buffs, " \ "minutes) values (" \ "%s, %s, %s, %s, %s, %s, %s, %s)" is_pm = filter_is_pm(mes) minutes = AMBUSH_MINUTES if 'ambush' in mes.text else USUAL_MINUTES if "Вы нашли странное укрытие. Некоторые символы в дверном проёме выглядят знакомо" in mes.text: minutes = 7 helpers = [] try: cursor.execute(request, (link, names, lvls, forward_message_date, mes.from_user.id, is_pm, buffs, minutes)) except psycopg2.IntegrityError: # logging.error(traceback.format_exc()) request = "select on_channel, helpers from mobs where link = %s" cursor.execute(request, (link,)) row = cursor.fetchone() helpers = row[1] if is_pm: if row[0]: bot.send_message(chat_id=mes.chat_id, text="Данный моб уже на канале", reply_to_message_id=mes.message_id) return request = "update mobs set on_channel = true where link = %s" cursor.execute(request, (link,)) minutes = AMBUSH_MINUTES if 'ambush' in mes.text else USUAL_MINUTES response, buttons, avg_lvl, remaining_time = get_mobs_text_and_buttons(mes.chat_id, link, names, lvls, helpers, forward_message_date, buffs, minutes, mes.from_user.id) player: Player = Player.get_player(mes.from_user.id) if is_pm and (player is None or player.castle == '🖤'): if 'It\'s an ambush!'.lower() in mes.text.lower(): bot.send_message(chat_id=mes.chat_id, text="Засады не отправляются на канал. " "Зовите бойцов вашей гильдии на помощь!") elif remaining_time <= datetime.timedelta(0): bot.send_message(chat_id=mes.chat_id, text="Время истекло. На канал не отправлено.") # elif re.search("(boar|wolf|bear)", mes.text) is not None and 'resist' in mes.text: # pass else: threading.Thread(target=send_mob_message_and_start_updating(bot, mes, player, response, buttons, is_pm, link, forward_message_date, [])).start() bot.send_message(chat_id=mes.chat_id, parse_mode='HTML', text="Отправлено на <a href=\"https://t.me/mobs_skala_cw3\">канал</a>, а также в " "<a href=\"https://t.me/CwMobsNotifyBot\">бота</a>. Спасибо!") if player is not None and player.has_api_access: cwapi.update_player(player.id, player=player) try: # requests.post('http://127.0.0.1:5555/addMob', # json=json.dumps({"castle": '🖤', "text": mes.text, "telegram_id": mes.from_user.id, # "forward_date": forward_message_date.timestamp()}, ensure_ascii=False), # timeout=0.3) pass # Верно! requests.post('http://144.91.112.129:5555/addMob', json=json.dumps({"castle": '🖤', "text": mes.text, "telegram_id": mes.from_user.id, "forward_date": forward_message_date.timestamp()}, ensure_ascii=False), timeout=0.3) except Exception: logging.error(traceback.format_exc()) else: ping, ping_list = [], [] if remaining_time > datetime.timedelta(0): if not is_pm: minus, plus = get_suitable_lvls(mes.text) ping_list = get_chat_helpers(mes.chat_id, minus, plus, avg_lvl, player) if ping_list: for pl in ping_list: on = pl.settings.get("mobs_notify") if on is None: on = True if on and pl.id != mes.from_user.id: ping.append(pl.username) if ping: threading.Thread(target=send_notify, args=(link, mes.chat_id, ping)).start() guild = Guild.get_guild(player.guild) if guild is None or guild.settings.get("mobs_hunt", True) is True or mes.chat_id != guild.chat_id: threading.Thread(target=send_mob_message_and_start_updating, args=( bot, mes, player, response, buttons, is_pm, link, forward_message_date, ping_list) ).start() return
def stock(bot, update): """ Выводит сток игрока (команда /stock) """ mes = update.message player = Player.get_player(mes.from_user.id) if player is None: return is_guild = False guild = None if 'guild' in mes.text or mes.text.startswith("/g_stock"): is_guild = True if player.guild is None: bot.send_message( chat_id=mes.from_user.id, text= "Вы не состоите в гильдии. Попросите командира добавить вас") return guild = Guild.get_guild(guild_id=player.guild) if guild is None: bot.send_message( chat_id=mes.from_user.id, text= "Вы не состоите в гильдии. Попросите командира добавить вас") return curr_stock = guild.api_info.get("stock") if curr_stock is None: bot.send_message( chat_id=mes.from_user.id, text= "Отсутствует информация о стоке. Для обновления нажмите /update_guild. " "Требуется доступ к API.") return else: if not player.stock: bot.send_message( chat_id=mes.chat_id, text= "Отсутствует информация о стоке. Для обновления нажмите /update_stock. " "Требуется доступ к API.") return curr_stock = player.stock """ res: Ресурсы alch: Травы misc: Корм, Зелья, свитки other: Остальное """ if 'res' in mes.text: stage = [0] elif 'alch' in mes.text: stage = [1] elif 'misc' in mes.text: stage = [2] elif 'equip' in mes.text: stage = [3] elif 'other' in mes.text: stage = [5] else: stage = [] response = "<b>📦Склад:\nРесурсы:</b>\n" stages = { 0: { "name": "Ресурсы:", "to_achieve": lambda code: True }, 1: { "name": "Травы", "to_achieve": lambda code: not code.isdigit() or int(code) >= 39 }, 2: { "name": "Корм:", "to_achieve": lambda code: not code.isdigit() or int(code) >= 618 }, 3: { "name": "Экипировка и крафт:", "to_achieve": lambda code: not code.isdigit() }, 4: { "name": "Зелья:", "to_achieve": lambda code: not code.isdigit() and code[0] not in ["k", "r", "w"] }, 5: { "name": "Другое:", "to_achieve": lambda code: not code.isdigit() and code[0] != "p" }, 6: { "name": "КОНЕЦ", "to_achieve": lambda code: False } } stage_num = 0 next_stage = stages.get(stage_num + 1) total_gold = 0 prices = cwapi.api_info.get("prices") or {} for code, count in list(curr_stock.items()): stage_changed = False new_response = "" while next_stage.get("to_achieve")(code): stage_changed = True stage_num += 1 next_stage = stages.get(stage_num + 1) if stage and stage_num not in stage: continue if stage_changed: new_response += "\n<b>{}</b>\n".format( stages.get(stage_num).get("name")) price = prices.get(code) or "❔" if len(code) > 4: name = code else: name = get_item_name_by_code(code) new_response += "<a href=\"https://t.me/share/url?url=/{}\">{} x {}</a> ≈ {}" \ "\n".format("{} {} {}".format("g_withdraw" if is_guild else "g_deposit", code, count), "{} | {}".format(code, name) if code != name else name, count, "<b>{}</b>💰({}💰x{})".format( price * count, price, count) if isinstance(price, int) else price) total_gold += price * count if isinstance(price, int) else 0 if len(response + new_response) > MAX_MESSAGE_LENGTH: bot.group_send_message(chat_id=mes.chat_id, text=response, parse_mode='HTML') response = "" response += new_response response += "\n\n<b>Всего: {}💰</b>\n".format(total_gold) if is_guild and guild is not None: stock_size, stock_limit = guild.api_info.get( "stock_size"), guild.api_info.get("stock_limit") if stock_size is not None and stock_limit is not None: response += "📦Сток гильдии: <b>{}</b> / <b>{}</b>\n".format( stock_size, stock_limit) response += "Последнее обновление: <em>{}</em>".format( guild.last_updated.strftime("%d/%m/%y %H:%M") if guild. last_updated is not None else "Неизвестно") elif not is_guild: response += "Последнее обновление: <em>{}</em>\n".format( player.api_info.get("stock_update") or "Неизвестно") bot.group_send_message(chat_id=mes.chat_id, text=response, parse_mode='HTML') bot.send_message_group(mes.chat_id)
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 mob(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) names, lvls, buffs = [], [], [] for string in mes.text.splitlines(): parse = re.search("(.+) lvl\\.(\\d+)", string) if parse is not None: name = parse.group(1) lvl = int(parse.group(2)) names.append(name) lvls.append(lvl) buffs.append("") else: parse = re.search(" ╰ (.+)", string) if parse is not None: buff = parse.group(1) buffs.pop() buffs.append(buff) 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 = "insert into mobs(link, mob_names, mob_lvls, date_created, created_player, on_channel, buffs, " \ "minutes) values (" \ "%s, %s, %s, %s, %s, %s, %s, %s)" is_pm = filter_is_pm(mes) minutes = 5 if 'ambush' in mes.text else 3 helpers = [] try: cursor.execute(request, (link, names, lvls, forward_message_date, mes.from_user.id, is_pm, buffs, minutes)) except psycopg2.IntegrityError: # logging.error(traceback.format_exc()) request = "select on_channel, helpers from mobs where link = %s" cursor.execute(request, (link,)) row = cursor.fetchone() helpers = row[1] if is_pm: if row[0]: bot.send_message(chat_id=mes.chat_id, text="Данный моб уже на канале", reply_to_message_id=mes.message_id) return request = "update mobs set on_channel = true where link = %s" cursor.execute(request, (link,)) minutes = 5 if 'ambush' in mes.text else 3 response, buttons, avg_lvl, remaining_time = get_mobs_text_and_buttons(link, names, lvls, helpers, forward_message_date, buffs, minutes, mes.from_user.id) player = Player.get_player(mes.from_user.id) if is_pm and (player is None or player.castle == '🖤'): if 'It\'s an ambush!'.lower() in mes.text.lower(): bot.send_message(chat_id=mes.chat_id, text="Засады не отправляются на канал. " "Зовите бойцов вашей гильдии на помощь!") elif remaining_time <= datetime.timedelta(0): bot.send_message(chat_id=mes.chat_id, text="Время истекло. На канал не отправлено.") # elif re.search("(boar|wolf|bear)", mes.text) is not None and 'resist' in mes.text: # pass else: threading.Thread(target=send_mob_message_and_start_updating(bot, mes, player, response, buttons, is_pm, link, forward_message_date)).start() bot.send_message(chat_id=mes.chat_id, parse_mode='HTML', text="Отправлено на <a href=\"https://t.me/mobs_skala_cw3\">канал</a>, а также в " "<a href=\"https://t.me/CwMobsNotifyBot\">бота</a>. Спасибо!") try: # requests.post('http://127.0.0.1:5555/addMob', # json=json.dumps({"castle": '🖤', "text": mes.text, "telegram_id": mes.from_user.id, # "forward_date": forward_message_date.timestamp()}, ensure_ascii=False), # timeout=0.3) pass # Верно! requests.post('http://144.91.112.129:5555/addMob', json=json.dumps({"castle": '🖤', "text": mes.text, "telegram_id": mes.from_user.id, "forward_date": forward_message_date.timestamp()}, ensure_ascii=False), timeout=0.3) except Exception: logging.error(traceback.format_exc()) else: if remaining_time > datetime.timedelta(0): ping_count = 0 if not is_pm: barracks = Location.get_location(1) try: ping_list = barracks.special_info.get("mobs_notify").get(str(mes.chat_id)).copy() except Exception: ping_list = None if not ping_list: ping_list = [] if player.guild is not None or ping_list: guild = Guild.get_guild(guild_id=player.guild) if guild.is_academy() and mes.chat_id == guild.chat_id: # Пинги для академки отключены return if guild is not None and guild.chat_id == mes.chat_id: ping_list += guild.members if ping_list: minus, plus = get_suitable_lvls(mes.text) ping = [] for pl_id in ping_list: pl = Player.get_player(pl_id) if avg_lvl - minus <= pl.lvl <= avg_lvl + plus: on = pl.settings.get("mobs_notify") if on is None: on = True if on and pl.id != mes.from_user.id: ping.append(pl.username) if ping: text = "Мобы!\n" for username in ping: text += "@{} ".format(username) ping_count += 1 if ping_count >= PING_LIMIT: bot.send_message(chat_id=mes.chat_id, text=text) text = "Мобы!\n" ping_count = 0 if text != "Мобы!\n": bot.send_message(chat_id=mes.chat_id, text=text) threading.Thread(target=send_mob_message_and_start_updating(bot, mes, player, response, buttons, is_pm, link, forward_message_date)).start() return
def get_player_and_guild_and_alliance(player_id: int): player = Player.get_player(player_id, notify_on_error=False) guild = Guild.get_guild(player.guild) if player is not None else None alliance = Alliance.get_alliance(guild.alliance_id) if guild is not None else None return player, guild, alliance
def hero(bot, update, user_data): mes = update.message text = mes.text castle = re.search("([🍁☘️🖤🐢🦇🌹🍆🎖]+)(.+)", text) nickname = castle.group(2) castle = castle.group(1) if castle != '🖤': pass # Игрок не из Скалы # bot.send_message(chat_id=mes.from_user.id, text="Пользователям не из Скалы запрещена регистрация!") # return player = Player.get_player(mes.from_user.id, notify_on_error=False) if player is not None and player.id == 402027858 and player.castle != '🖤' and castle == '🖤': # Рыбак вернулся! bot.send_message( chat_id=player.id, text= "Стражи с гулким стуком ударяют копьями о землю. Врата медленно " "отворяются, открывая взору такие знакомые, но в то же время изменившиеся улицы.\n" "<b>С возвращением домой!</b>", parse_mode='HTML') if player is None and mes.chat_id != mes.from_user.id: # Добавление новых пользователей только в личке у бота return forward_message_date = utc.localize( mes.forward_date).astimezone(tz=moscow_tz).replace(tzinfo=None) print(forward_message_date) if datetime.datetime.now() - forward_message_date > datetime.timedelta(seconds=30) and \ mes.from_user.id not in urned_players: bot.send_message(chat_id=mes.chat_id, text="Это устаревший профиль.", reply_to_message_id=mes.message_id) return # Парсинг хиро guild_tag = re.search("[🍁☘🖤🐢🦇🌹🍆🎖]\\[(.+)\\]", text) if guild_tag: guild_tag = guild_tag.group(1) lvl = int(re.search("🏅Уровень: (\\d+)", text).group(1)) attack = int(re.search("⚔Атака: (\\d+)", text).group(1)) defense = int(re.search("🛡Защита: (\\d+)", text).group(1)) stamina = int(re.search("🔋Выносливость: \\d+/(\\d+)", text).group(1)) pet = re.search("Питомец:\n.(\\s.+\\(\\d+ lvl\\))", text) exp = int(re.search("🔥Опыт: (\\d+)", text).group(1)) last_updated = datetime.datetime.now(tz=moscow_tz).replace(tzinfo=None) if pet: pet = pet.group(1) # Парсинг экипировки print("parsing eq") player_equipment = { "main_hand": None, "second_hand": None, "head": None, "gloves": None, "armor": None, "boots": None, "cloaks": None } equip_strings = text.partition("🎽Экипировка")[2].splitlines()[1:] for string in equip_strings: # clear_name = re.search("\\+?\\d?\\s?(.+?)\\s\\+", string) clear_name = re.search( "(⚡?\\+?\\d*\\s?(.+?))\\s\\+((\\d*)⚔)?\\s*\\+?(\\d*)🛡?", string) if clear_name is None: # logging.warning("Error while parsing item_string\n{}".format(string)) continue else: pass # logging.info("successful parsed {},, Got: {}".format(string, clear_name.group(1))) full_name = clear_name.group(1) eq_attack = int(clear_name.group(4)) if clear_name.group( 4) is not None and clear_name.group(4) != "" else 0 eq_defense = int( clear_name.group(5)) if clear_name.group(5) != "" else 0 clear_name = clear_name.group(2) eq = get_equipment_by_name(clear_name) if eq is None: logging.warning( "Equipment with name {} is None".format(clear_name)) continue eq.name = full_name eq.attack = eq_attack eq.defense = eq_defense player_equipment.update({eq.place: eq}) if player is None: if mes.from_user.username is None: bot.send_message( chat_id=mes.chat_id, text= "Регистрация без имени пользователя невозможна. Пожалуйста, " "установите его в настройках аккаунта Telegram") return player = Player(mes.from_user.id, mes.from_user.username, nickname, guild_tag, None, lvl, attack, defense, stamina, pet, player_equipment, castle=castle, last_updated=last_updated, created=last_updated, exp=exp) # Добавляем игрока в бд player.insert_into_database() player = player.reload_from_database() user_data.update({"status": DEFAULT_CASTLE_STATUS, "location_id": 0}) bot.send_message( chat_id=mes.chat_id, text= "Добро пожаловать в 🖤Скалу, <b>{}</b>!\n\n<a href=\"https://t.me/joinchat/DdKE7kUfsmDVIC2DJymw_A\">Чат центральной площади</a>\n\nДля добавления информации о классе " "необходимо прислать ответ @ChatWarsBot на кнопку \"🏅Герой\" (рекомендуется сделать для " "получения доступа к некоторых дополнительным фишкам, особенно стражникам).\n\n" "<em>Вы всегда можете отключить рп составляющую бота командой </em>/change_rp.<em> " "Обратите внимание, что это сделает недоступными некоторые функции " "бота.</em>".format(player.nickname), parse_mode='HTML') if filter_is_pm(mes): send_general_buttons(mes.from_user.id, user_data) auth(bot, update) else: # Обновляем существующую информацию player.username = mes.from_user.username player.nickname = nickname player.guild_tag = guild_tag player.lvl = lvl player.attack = attack player.defense = defense player.stamina = stamina player.pet = pet player.equipment = player_equipment player.castle = castle player.last_updated = last_updated player.exp = exp player.update() bot.send_message(chat_id=mes.chat_id, text="Профиль успешно обновлён, <b>{}</b>!".format( player.nickname), parse_mode='HTML') if player.guild is not None: guild = Guild.get_guild(player.guild) guild.calculate_attack_and_defense() guild.sort_players_by_exp()
def view_profile(bot, update): mes = update.message requested_player_id = mes.from_user.id requested_player = Player.get_player(requested_player_id) if requested_player is None: return has_access = True guild = Guild.get_guild(guild_id=requested_player.guild) if not check_whois_access(requested_player_id): if guild is None or not guild.check_high_access(requested_player_id): # bot.send_message(chat_id=mes.chat_id, text="Право распоряжаться людьми необходимо заслужить.", # reply_to_message_id=mes.message_id) has_access = False # Доступ к хуизу есть reply = False if mes.text.startswith("/dok") or mes.text.startswith("/doc"): if mes.reply_to_message is not None: # Реплай в чате reply = True player_ids = [mes.reply_to_message.from_user.id] elif has_access is False: return elif "@" in update.message.text: # Поиск по юзерке player_ids = [] for username in mes.text.split()[1:]: request = "select id from players where username = %s" cursor.execute(request, (username.partition("@")[2], )) row = cursor.fetchone() if row is None: bot.send_message( chat_id=mes.chat_id, text="Игрок {} не найден.".format(username)) continue player_ids.append(row[0]) if not player_ids: return else: # Поиск по нику в игре request = "select id from players where lower(nickname) = %s or lower(nickname) like %s" # print(request % mes.text.partition(" ")[2] % "%]" + mes.text.partition(" ")[2]) cursor.execute(request, (mes.text.partition(" ")[2].lower(), "%]" + mes.text.partition(" ")[2].lower())) row = cursor.fetchone() if row is None: bot.send_message(chat_id=mes.chat_id, text="Игрок не найден.") return player_ids = [row[0]] else: player_id = re.search("_(\\d+)", mes.text) player_ids = [int(player_id.group(1))] if not player_ids: bot.send_message(chat_id=mes.chat_id, text="Неверный синтаксис.") return for player_id in player_ids: player = Player.get_player(player_id) if player is None or (mes.text.startswith("/view_profile") and (guild is None or player.guild != guild.id)): if player is not None and player.guild is not None: guild = Guild.get_guild(player.guild) if guild is not None: if requested_player_id in guild.assistants or requested_player_id == guild.commander_id: pass else: bot.send_message(chat_id=mes.chat_id, text="Игрок не найден.") return if reply and player.status is not None: # Сообщение со статусом bot.send_message(chat_id=mes.chat_id, text=get_status_message_by_text( get_status_text_by_id(player.status, player.id)), parse_mode='HTML', reply_to_message_id=mes.message_id) on_doc_status(requested_player) if not has_access: bot.send_message( chat_id=mes.chat_id, text="Право распоряжаться людьми необходимо заслужить.", reply_to_message_id=mes.message_id) return buttons = get_profile_buttons(player) if (player.guild is None or player.guild != requested_player.guild ) and not check_whois_access(requested_player_id): guild = Guild.get_guild(guild_id=player.guild) bot.send_message( chat_id=mes.from_user.id, text= "Вы не знаете этого человека, однако его форма позволяет вам сделать вывод, что он " "служит {}".format( "в гильдии <b>{}</b>".format(guild.tag) if guild is not None else "как вольный наёмник (без гильдии)"), parse_mode='HTML', reply_markup=buttons) return buttons = get_profile_buttons(player, whois_access=True) response = get_profile_text(player, self_request=False, requested_player=requested_player) bot.send_message(chat_id=mes.from_user.id, text=response, parse_mode='HTML', reply_markup=buttons)
def check_whois_access(user_id): try: return check_access(user_id) or user_id == MERC_ID or user_id in trade_divisions_access_list or \ Guild.get_guild(guild_tag="АКАДЕМИЯ").check_high_access(user_id) except Exception: return False
def get_profile_text(player, self_request=True, user_data=None, requested_player=None): barracks = Location.get_location(1) class_links = barracks.special_info.get("class_links") if class_links is None: class_links = {} barracks.special_info.update({"class_links": class_links}) try: class_format = (classes_to_emoji.get(player.game_class) + player.game_class) if \ player.game_class is not None else "Воин" except Exception: class_format = "Воин" logging.error(traceback.format_exc()) logging.error("id:{} nickname:{} class:{} username:{}".format( player.id, player.nickname, player.game_class, player.username)) response = "<b>{}</b> - {} {}\n".format( player.nickname, class_format, "🖤Скалы" if player.castle == '🖤' else player.castle) response += "{}id: <code>{}</code>, ".format( "@{}, ".format(player.username) if player.username is not None else "", player.id) if user_data is None: user_data = dispatcher.user_data.get(player.id) if player.status is not None: response += "Статус: <b>{}</b>\n".format( get_status_text_by_id(player.status, player.id)) response += "🏅: <code>{}</code>, 🔥: <code>{}</code> ⚔: <code>{}</code>, 🛡: <code>{}</code>" \ "\n".format(player.lvl, player.exp or "???", player.attack, player.defense) response += ("👝: {}, ".format(player.pogs) if player.pogs is not None else "") + \ "🔘: <code>{}</code>\n".format(player.reputation) guild = Guild.get_guild( guild_id=player.guild) if player.guild is not None else None response += "Гильдия: {} | {}🔋\n".format( "<code>{}</code>".format(guild.tag) if guild is not None else "нет", player.stamina) if guild is not None and self_request: response += "Покинуть гильдию: /leave_guild\n" elif guild is not None and guild.check_high_access(requested_player.id) and \ (requested_player.guild == guild.id or guild.is_academy()): response += "Удалить из гильдии: /remove_player_{}\n".format(player.id) if self_request: if player.game_class is not None and player.castle == '🖤' and player.game_class not in [ 'Master', 'Esquire' ]: try: if class_links.get(player.game_class) is None: revoke_class_link(player.game_class) invite_link = class_links.get(player.game_class) response += "<a href=\"{}\">\n📚Классовый чат</a>\n".format( "https://t.me/joinchat/" + invite_link) except Exception: logging.error(traceback.format_exc()) response += "\nЭкипировка:\n" eq_list = list(player.equipment.values()) for equipment in eq_list: if equipment is None: continue response += equipment.format() r1, r2, r3 = player.get_reports_count() try: if guild is not None and guild.commander_id == player.id: response += "\n<b>🎗Командир гильдии</b>\n" if guild is not None and player.id in guild.assistants: response += "\n<b>🎗Зам командира гильдии</b>\n" except Exception: logging.error(traceback.format_exc()) response += "\nРепорты(эта неделя / прошлая / всего): <code>{}</code> / <code>{}</code> / <code>{}</code>" \ "\n".format(r1, r2, r3) response += "Регистрация в боте: <code>{}</code>\n".format( player.created.strftime("%d/%m/%y %H:%M:%S") if player. created is not None else "Оппозит") response += "Последнее обновление профиля: " \ "<code>{}</code>\n".format(player.last_updated.strftime("%d/%m/%y %H:%M:%S") if player.last_updated is not None else "неизвестно") if user_data is None: return response status = user_data.get("status") if status is not None and status in ["sawmill", "quarry", "construction" ] or "quest_name" in user_data: if "quest_name" in user_data: quest_name = user_data.get("quest_name") response += "\n<b>Вы {}. Это займёт несколько минут.</b>" \ "".format("на разведке" if quest_name == 'exploration' else "копаете котлован" if quest_name == 'pit' else "") else: if player is not None: j = construction_jobs.get(player.id) if j is not None: seconds_left = j.get_time_left() response += "\nВы заняты делом. Окончание через <b>{:02.0f}:{:02.0f}</b>" \ "".format(seconds_left // 60, (seconds_left % 60) // 1) return response
def battle_stats(bot, update): mes = update.message cursor1 = conn.cursor() battle_id = re.search("_(\\d+)", mes.text) battle_id = int( battle_id.group(1)) if battle_id is not None else count_battle_id(mes) guilds = [] for guild_id in Guild.guild_ids: guild = Guild.get_guild(guild_id=guild_id) if guild is None or guild.division in SKIPPED_DIVISIONS: continue guild.clear_counted_reports() guilds.append(guild) guilds.sort(key=lambda x: x.division or "") guilds.append( Guild(-1, "Без гильдии", None, None, None, None, None, None, None, None, None, None, None, None)) request = "select player_id, attack, defense, gold from reports where battle_id = %s" cursor1.execute(request, (battle_id, )) row = cursor1.fetchone() response = "Статистика по битве {} - {}:\n".format( battle_id, count_battle_time(battle_id).strftime("%d/%m/%y %H:%M:%S")) while row is not None: player = Player.get_player(row[0]) if player.castle != '🖤': row = cursor1.fetchone() continue if player.guild is None: guild = guilds[-1] else: guild = Guild.get_guild(player.guild) guild.add_count_report(row[1], row[2], row[3]) row = cursor1.fetchone() total_reports = 0 total_attack = 0 total_defense = 0 total_gold = 0 guilds.sort(key=lambda x: (x.division or "", x.get_counted_report_values()[1]), reverse=True) current_division = guilds[0].division division_reports, division_attack, division_defense, division_gold = 0, 0, 0, 0 for guild in guilds: if guild.division != current_division: response += "Дивизион {}:\nВсего: {} репортов, ⚔️: <b>{}</b>, 🛡: <b>{}</b>, 💰: <b>{}</b>\n\n" \ "".format(current_division, division_reports, division_attack, division_defense, division_gold) total_attack += division_attack total_defense += division_defense total_gold += division_gold total_reports += division_reports division_reports, division_attack, division_defense, division_gold = 0, 0, 0, 0 current_division = guild.division values = guild.get_counted_report_values() division_reports += values[0] division_attack += values[1] division_defense += values[2] division_gold += values[3] response += "<code>{:<3}</code>-👣{} ⚔️{} 🛡{} 💰{}" \ "\n".format(guild.tag, values[0], values[1], values[2], values[3]) response += "\nВсего: {} репортов, ⚔️: <b>{}</b>, 🛡: <b>{}</b>, " \ "💰: <b>{}</b>\n".format(total_reports, total_attack, total_defense, total_gold) bot.send_message(chat_id=mes.chat_id, text=response, parse_mode='HTML')
def get_alliance_guilds(self): request = "select guild_id from guilds where alliance_id = %s" cursor.execute(request, (self.id, )) return list( map(lambda guild_id: Guild.get_guild(guild_id[0]), cursor.fetchall()))
def get_general_buttons(user_data, player=None, only_buttons=False): status = user_data.get("status") rp_off = user_data.get("rp_off") buttons = None if rp_off and status in ["central_square", "rp_off"]: buttons = [[ KeyboardButton("👀 Профиль"), KeyboardButton("👥 Гильдия"), KeyboardButton("📈Топы"), ], [ KeyboardButton("🔖Связь с МИД"), KeyboardButton("🗂Обновления"), KeyboardButton("📰Инструкция"), ]] if player is not None: if player.guild is not None: guild = Guild.get_guild(player.guild) if guild is not None: if guild.check_high_access(player.id): pass # buttons[0].append(KeyboardButton("📜Список гильдий")) elif status is None or status in ["default", "central_square"]: status = "central_square" user_data.update({"status": status}) buttons = [ [ KeyboardButton(Location.get_location(1).name), KeyboardButton(Location.get_location(2).name), KeyboardButton("⛩ Врата замка"), ], [ KeyboardButton("🔭 Башня ТехМаг наук"), # ❗ KeyboardButton("🏤Мандапа Славы"), # KeyboardButton("📈Топы"), # KeyboardButton("🏚 Не построено"), ], [ KeyboardButton("↔️ Подойти к указателям"), KeyboardButton("🏚 Стройплощадка"), # KeyboardButton("↩️ Назад"), ] ] # Стройка Мандапы Славы окончена # hall = Location.get_location(8) # if hall is not None and hall.is_constructed(): # buttons[1].insert(1, KeyboardButton("🏤Мандапа Славы")) tea_party = Location.get_location(9) if tea_party is not None and tea_party.is_constructed(): buttons[1].insert(2, KeyboardButton("🍵Чайная лига")) elif status == 'barracks': buttons = [[ KeyboardButton("👀 Посмотреть в зеркало"), KeyboardButton("👥 Посмотреть ведомость гильдии"), ], [ KeyboardButton("↩️ Назад"), ]] if player is not None: if player.guild is not None: guild = Guild.get_guild(player.guild) if guild is not None: if guild.alliance_id is not None: buttons.insert(1, [KeyboardButton(" 🤝Альянс")]) if guild.check_high_access(player.id): pass # buttons.insert(1, [KeyboardButton("📜Изучить список гильдий")]) elif status == 'throne_room': buttons = [ [ KeyboardButton("Обратиться к командному составу"), KeyboardButton("Попросить аудиенции у 👑Короля"), ], [ KeyboardButton("🎇Посмотреть на портреты"), # KeyboardButton("💰Сокровищница"), ], [ KeyboardButton("↩️ Назад"), ] ] if player is not None and check_access(player.id): buttons[1].append(KeyboardButton("Штаб")) if player is not None and player.id in [king_id, SUPER_ADMIN_ID]: buttons[1].append(KeyboardButton("Кабинет Короля")) elif status in [ 'mid_feedback', 'duty_feedback', 'sending_guild_message', 'editing_debrief', 'changing_castle_message', 'sending_bot_guild_message', 'editing_update_message', "treasury", "awaiting_roulette_bet" ]: buttons = [[ KeyboardButton("↩️ Назад"), ]] elif status in ["sawmill", "quarry", "construction", "exploration", "pit"]: buttons = [[ KeyboardButton("👀 Профиль"), ], [ KeyboardButton("↩️ Отмена"), ]] elif status == 'castle_gates': on_duty = user_data.get("on_duty") print(on_duty, user_data) if on_duty: buttons = [ [ KeyboardButton("Покинуть вахту"), ], ] else: buttons = [[ KeyboardButton("🌲Лесопилка"), KeyboardButton("⛰Каменоломня"), ], [ KeyboardButton("Обратиться к 💂♂Стражам"), ], [ KeyboardButton("↩️ Назад"), ]] print(player, player.game_class if player is not None else "") if player is not None and player.game_class == "Sentinel": # Только для стражей, захардкожено buttons[0].append(KeyboardButton("Заступить на вахту")) elif status == 'king_cabinet': buttons = [[ KeyboardButton("Добавить генерала"), KeyboardButton("Изменить сообщение"), ], [ KeyboardButton("Начать стройку"), ], [ KeyboardButton("↩️ Назад"), ]] elif status == 'headquarters': buttons = [[ KeyboardButton("📜Выкатить дебриф"), KeyboardButton("📣Рассылка по гильдиям"), ], [ KeyboardButton("↩️ Назад"), ]] elif status == 'technical_tower': buttons = [ [ # KeyboardButton("🔖Обратиться к магу"), KeyboardButton("📰Манускрипт"), KeyboardButton("🗂Архив объявлений"), ], [ KeyboardButton("🧾История коммитов"), ], [ KeyboardButton("↩️ Назад"), ] ] if player is not None and player.id == SUPER_ADMIN_ID: buttons[1].insert(1, KeyboardButton("💻Кабинет ботодела")) elif status == 'my_cabinet': buttons = [[ KeyboardButton("📈Выкатить обнову"), KeyboardButton("📣Рассылка по гильдиям"), ], [ KeyboardButton("↩️ Назад"), ]] elif status == 'construction_plate': location = Location.get_location(status_to_location.get(status)) buttons = location.buttons elif status == 'hall_of_fame': buttons = [ [ KeyboardButton("📈Топы"), # KeyboardButton("📣Ещё кнопка, хз что"), ], [ KeyboardButton("↩️ Назад"), ] ] elif status == 'tops': buttons = [[ KeyboardButton("⚔️Атака"), KeyboardButton("🛡Защита"), KeyboardButton("🔥Опыт"), ], [ KeyboardButton("↩️ Назад"), ]] if not rp_off: buttons.insert(1, [ KeyboardButton("🌲Дерево"), KeyboardButton("⛰Камень"), KeyboardButton("🏚Стройка"), ]) elif status == 'manuscript': buttons = [ [ KeyboardButton("👤Игроки"), KeyboardButton("👥Гильдии"), KeyboardButton("📓Гайды"), ], [ KeyboardButton("🖋Триггеры"), KeyboardButton("📦Сток"), # KeyboardButton("🏠Профсоюзы"), ], [ KeyboardButton("↩️ Назад"), ] ] if not rp_off: buttons[1].insert(0, KeyboardButton("↔️Указатели")) elif status == 'guides': buttons = [[ KeyboardButton("⚗️Алхимик"), KeyboardButton("⚒Кузнец"), KeyboardButton("📦Добытчик"), ], [ KeyboardButton("🏹Лучник"), KeyboardButton("⚔Рыцарь"), KeyboardButton("🛡Защитник"), ], [ KeyboardButton("↩️ Назад"), ]] elif status == 'tea_party': buttons = [ # [ # KeyboardButton("Разведка"), # KeyboardButton("Рыть котлован"), # ], [ KeyboardButton("🎰Рулетка"), KeyboardButton("💲Магазин статусов"), ], [ KeyboardButton("🧳Контрабандист"), ], [ KeyboardButton("↩️ Назад"), ], ] elif status == 'roulette': buttons = [ [ KeyboardButton("🔸Сделать ставку"), KeyboardButton("📈Топы в рулетке"), ], [KeyboardButton("↩️ Назад")], ] if only_buttons or buttons is None: return buttons return ReplyKeyboardMarkup(buttons, resize_keyboard=True)
def send_withdraw(bot, update, *args): manual = False if args and args[0] == "custom_request": manual = True give = args[1] chat_id = update player = Player.get_player(chat_id) else: chat_id = update.message.chat_id player = Player.get_player(update.message.from_user.id) give = {} mes = update.message if not isinstance(update, int) else None response, response_full = "/g_withdraw ", "/g_withdraw " res_count = 0 if player is None: return guild_stock = None if player.guild is not None: guild = Guild.get_guild(guild_id=player.guild) if guild.settings is not None: if guild.settings.get("withdraw") is False: if guild.chat_id == mes.chat_id: return guild_stock = guild.api_info.get("stock") if manual: pass elif "дай" in mes.text.lower(): # Выдача ресурсов по Дай x y potions_dict = { "фр": ["p01", "p02", "p03"], "фд": ["p04", "p05", "p06"], "грид": ["p07", "p08", "p09"], "натуру": ["p10", "p11", "p12"], "ману": ["p13", "p14", "p15"], "твайлайт": ["p16", "p17", "p18"], "морф": ["p19", "p20", "p21"] } parse = mes.text.lower().split()[1:] mode = "name" names = [] for string in parse: if mode == "quantity": mode = "name" try: quantity = int(string) if quantity > 0: if not names: continue for name in names: give.update({name: quantity}) continue except ValueError: pass if mode == "name": mode = "quantity" potions = potions_dict.get(string) if potions is None: if string not in list(resources) and string not in list(equipment_names) and string not in \ list(resources_reverted) and re.match("[rkp]\\d\\d?", string) is None: mode = "name" continue names = [ string ] # Список из имён, к которым далее следует количество для выдачи give.update({string: 1}) else: names = [] for p in potions: give.update({p: 1}) names.append(p) else: text = update.message.text.partition("In your stock:") text = text[2] or text[0] for string in text.splitlines(): if "Нет нужных материалов" in mes.text: parse = re.search("([^\n$]+) x (\\d+)", string) if parse is None: continue count = int(parse.group(2)) name = parse.group(1) code = resources.get(name) else: parse = re.search("(\\d+) x ([^\n$]+)", string) if parse is None: continue count = int(parse.group(1)) name = parse.group(2) code = resources.get(name) if code is None: code = get_item_code_by_name(name) if code is None: continue give.update({code: count}) not_enough = "" for code, count in list(give.items()): if guild_stock is not None: # Есть данные о стоке, проверка наличия ресурсов in_stock = guild_stock.get(code) or 0 if in_stock > 0: response += "{} {} ".format(code, min(count, in_stock)) if in_stock < count: not_enough += "{} x {}\n".format(get_item_name_by_code(code), count - in_stock) response_full += "{} {} ".format(code, count) res_count += 1 if res_count >= WITHDRAW_MESSAGE_LIMIT: response = format_all_withdraws(response, response_full, not_enough) bot.send_message(chat_id=chat_id, text=response, parse_mode='HTML') response, response_full, not_enough = "/g_withdraw ", "/g_withdraw ", "" res_count = 0 if res_count > 0: response = format_all_withdraws(response, response_full, not_enough) bot.send_message(chat_id=chat_id, text=response, parse_mode='HTML')
def check_vote_ability(self): """ Метод проверки возможности игрока голосовать """ from castle_files.libs.guild import Guild return self.castle == HOME_CASTLE and self.guild is not None and not Guild.get_guild(self.guild).is_academy()
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())
def set_vote_variant(bot, update): data = update.callback_query.data mes = update.callback_query.message player = Player.get_player(update.callback_query.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 parse = re.search("_(\\d+)_(\\d+)", data) if parse is None: bot.send_message(chat_id=mes.chat_id, text="Неверный синтаксис.") return vote_id = int(parse.group(1)) variant = int(parse.group(2)) 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') bot.answerCallbackQuery(callback_query_id=update.callback_query.id) return except Exception: logging.error(traceback.format_exc()) if vote.started + vote.duration < datetime.datetime.now(tz=moscow_tz).replace(tzinfo=None): bot.send_message(chat_id=mes.chat_id, text="Голосование уже завершено.") return for ch in vote.choices: if player.id in ch: ch.remove(player.id) vote.choices[variant].append(player.id) vote.update() choice = None for i, ch in enumerate(vote.choices): if player.id in ch: choice = i break response = get_vote_text(vote, choice=choice) buttons = get_vote_buttons(vote, choice=choice) try: bot.editMessageText(chat_id=mes.chat_id, message_id=mes.message_id, text=response, reply_markup=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)