def two_quest_pressed_go(bot, update, user_data: dict): mes = update.message pair_player_id, quest = user_data.get("pair_id"), user_data.get("quest") pair_user_data = dispatcher.user_data.get(pair_player_id) if pair_user_data is None: logging.error("Pair user_data is None for {}".format(mes.from_user.id)) return try: j = construction_jobs.get(mes.from_user.id) if j is None: j = construction_jobs.get(pair_player_id) j.job.schedule_removal() except Exception: logging.error(traceback.format_exc()) pressed = pair_user_data.get("quest_pressed") if not pressed: # Нажал первый игрок (ждём второго) user_data.update({"quest_pressed": True}) safe_job_create(two_action_timeout, 30, mes.from_user.id, {"ids": [mes.from_user.id, pair_player_id]}) bot.send_message(chat_id=mes.from_user.id, text="Принято! Ожидайте соратника.") return # Нажали оба игрока player, pair_player = Player.get_player(mes.from_user.id), Player.get_player(pair_player_id) qst = quest_texts[quest]["two_players"][user_data["quest_id"]] first_text = qst.get("first_success") second_text = qst.get("second_success") or first_text return_from_quest(player.id, user_data) return_from_quest(pair_player.id, pair_user_data) player.reputation += GO_NOT_SUCCESS_REPUTATION pair_player.reputation += GO_NOT_SUCCESS_REPUTATION player.update() pair_player.update() buttons = get_general_buttons(user_data, player) bot.send_message(chat_id=player.id, text=first_text + "\nПолучено {}🔘".format(GO_SUCCESS_REPUTATION), reply_markup=buttons) bot.send_message(chat_id=pair_player_id, text=second_text + "\nПолучено {}🔘".format(GO_SUCCESS_REPUTATION), reply_markup=buttons) now = datetime.datetime.now(tz=moscow_tz).replace(tzinfo=None) request = "insert into castle_logs(player_id, action, result, date, additional_info) values (%s, %s, %s, %s, %s)" cursor.execute(request, (player.id, quest, 1, now, json.dumps({"result": "two_players_success", "pair_player_id": pair_player_id}))) cursor.execute(request, (pair_player_id, quest, 1, now, json.dumps({"result": "two_players_success", "pair_player_id": player.id})))
def get_text_to_general_buttons(user_data, player=None): """ Возвращает текст, который нужно отправить по умолчанию с статусом в user_data :param user_data: Словарь user_data, функция использует значения 'status' и 'rp_off' :param player: Player :return: Str """ status = user_data.get("status") location_id = user_data.get("location_id") rp_off = user_data.get("rp_off") if location_id is None: user_data.update({"location_id": 0}) print(rp_off, status) if rp_off and status in ["central_square", "rp_off"]: return "Доброго времени суток!\nВыберите действие:" if status is None or status == "default": return "Вы входите в замок Скалы. Выберите, куда направиться!" if status in ["construction", "sawmill", "quarry"]: if player is not None: j = construction_jobs.get(player.id) if j is not None: seconds_left = j.get_time_left() return "Вы заняты делом. Окончание через <b>{:02.0f}:{:02.0f}</b>".format( seconds_left // 60, (seconds_left % 60) // 1) if location_id is not None: return Location.get_location_enter_text_by_id(location_id, player=player)
def construct(bot, update, user_data): mes = update.message location_id = None for loc in list(locations.values()): if loc.name == mes.text: location_id = loc.id break if mes.text == '/build_teaparty': location_id = 9 if location_id is None: send_general_buttons(mes.from_user.id, user_data=user_data, bot=bot) return location = Location.get_location(location_id) if location is None: bot.send_message(chat_id=mes.chat_id, text="Локация не найдена.") return if location.state is True or location.building_process < 0: bot.send_message(chat_id=mes.chat_id, text="Локация уже построена или стройка не начиналась.") return context = [update.message.from_user.id, user_data] j = job.run_once(callback=construction_return, when=CONSTRUCTION_DURATION_SECONDS, context=context) old_j = construction_jobs.get(update.message.from_user.id) if old_j is not None: old_j.job.schedule_removal() construction_jobs.update({update.message.from_user.id: MyJob(j, CONSTRUCTION_DURATION_SECONDS)}) user_data.update({"status": "construction", "construction_id": location.id}) buttons = get_general_buttons(user_data) bot.send_message(chat_id=update.message.chat_id, text="Вы отправились на стройку. Это займёт 5 минут.", reply_markup=buttons)
def safe_job_create(callback, when, player_id, context=None, cancel_old=True): j = job.run_once(callback=callback, when=when, context=context) if cancel_old: old_j = construction_jobs.get(player_id) if old_j is not None: old_j.job.schedule_removal() construction_jobs.update({player_id: MyJob(j, when)}) return j
def quarry(bot, update, user_data): user_data.update({"status": "quarry"}) buttons = get_general_buttons(user_data) bot.send_message(chat_id=update.message.chat_id, text="Вы отправились добывать камень. Это займёт примерно 3 минуты", reply_markup=buttons) context = [update.message.from_user.id, user_data] j = job.run_once(callback=resource_return, when=MINING_QUEST_DURATION_SECONDS, context=context) old_j = construction_jobs.get(update.message.from_user.id) if old_j is not None: old_j.job.schedule_removal() construction_jobs.update({update.message.from_user.id: MyJob(j, MINING_QUEST_DURATION_SECONDS)})
def sawmill(bot, update, user_data): user_data.update({"status": "sawmill"}) buttons = get_general_buttons(user_data) bot.send_message(chat_id=update.message.chat_id, text="Вы отправились добывать дерево. Это займёт примерно 3 минуты.\n\nВы можете вернуться " "мгновенно. В этом случае вся добыча будет утеряна.", reply_markup=buttons) context = [update.message.from_user.id, user_data] j = job.run_once(callback=resource_return, when=MINING_QUEST_DURATION_SECONDS, context=context) old_j = construction_jobs.get(update.message.from_user.id) if old_j is not None: old_j.job.schedule_removal() construction_jobs.update({update.message.from_user.id: MyJob(j, MINING_QUEST_DURATION_SECONDS)})
def return_from_quest(player_id, user_data): with quest_lock: for lst in list(quest_players.values()): try: lst.remove(player_id) except ValueError: pass delete_list = ["quest", "quest_pressed", "quest_id", "pair_id", "quest_name"] for string in delete_list: if string in user_data: user_data.pop(string) user_data.update({"status": "tea_party"}) j = construction_jobs.get(player_id) try: j.job.schedule_removal() construction_jobs.pop(player_id) except Exception: logging.error(traceback.format_exc()) pass
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