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 request_roulette_bet(bot, update, user_data): """ Запрос ставки в рулетке """ mes = update.message user_data.update({"status": "awaiting_roulette_bet"}) roulette = Location.get_location(10) placed = roulette.special_info["placed"].get(str(mes.from_user.id)) if placed is None: placed = 0 buttons = get_general_buttons(user_data) player = Player.get_player(mes.from_user.id) if player is None: return bot.send_message( chat_id=update.message.from_user.id, text= "Введите количество 🔘жетонов для ставки:\nМинимальная ставка: 10🔘\n\n" "Ваша ставка: <b>{}</b>🔘.\n" "Доступно: <b>{}</b>🔘.{}\n\n<em>Обратите внимание, отменить ставку невозможно.</em>" "".format( placed, player.reputation, "\nМаксимальная ставка: <b>{}</b>🔘".format(ROULETTE_MAX_BET_LIMIT) if datetime.datetime.now(tz=moscow_tz).replace(tzinfo=None).time() < datetime.time(hour=ROULETTE_HOUR_LIMIT) else ""), reply_markup=buttons, parse_mode='HTML')
def tea_party_quest(bot, update, user_data): mes = update.message player = Player.get_player(mes.from_user.id) if player is None: return quests = {"разведка": "exploration", "котлован": "pit"} quest = None for key, v in list(quests.items()): if key.lower() in mes.text.lower(): quest = v break if quest is None: logging.error("Quest is None") return user_data.update({"status": quest, "quest_name": quest}) with quest_lock: lst: [int] = quest_players.get(quest) # lst.append(player.id) buttons = get_general_buttons(user_data) bot.send_message(chat_id=mes.chat_id, text="Ты куда-то отправился. Вернуться невозможно. /f", reply_markup=buttons) safe_job_create(two_go_action, 5, player.id, { "quest": quest, "player_id": player.id })
def resource_return(bot, job): cursor = conn.cursor() if job.context[1].get("status") not in ["sawmill", "quarry"]: logging.warning( "Status not in [\"sawmill\", \"quarry\"], status = {}".format( job.context[1].get("status"))) return statuses_to_res = {"sawmill": "wood", "quarry": "stone"} res = statuses_to_res.get(job.context[1].get("status")) count = 1 throne = Location.get_location(2) throne.treasury.change_resource(res, count) player = Player.get_player(job.context[0]) player.reputation += 3 player.update_to_database() job.context[1].update({"status": "castle_gates"}) buttons = get_general_buttons(job.context[1], player) if job.context[0] in construction_jobs: try: construction_jobs.pop(job.context[0]) except Exception: logging.error(traceback.format_exc()) request = "insert into castle_logs(player_id, action, result, additional_info, date) values (%s, %s, %s, %s, %s)" cursor.execute( request, (player.id, "collect_resources", 1, json.dumps({ "resource": res, "count": count }), datetime.datetime.now(tz=moscow_tz).replace(tzinfo=None))) bot.send_message(chat_id=job.context[0], text="Вы успешно добыли {}. Казна обновлена. Получено 3 🔘" "".format("дерево" if res == "wood" else "камень"), reply_markup=buttons) on_resource_return(player, res)
def two_action_timeout(bot, cur_job): player_id, pair_player_id = cur_job.context.get("ids") player, pair_player = Player.get_player(player_id), Player.get_player(pair_player_id) user_data, pair_user_data = dispatcher.user_data.get(player_id), dispatcher.user_data.get(pair_player_id) status, quest = user_data.get("status"), user_data.get("quest") if status != "two_quest": return qst = quest_texts[quest]["two_players"][user_data["quest_id"]] first_text = qst.get("first_fail") second_text = qst.get("second_fail") or first_text return_from_quest(player_id, user_data) return_from_quest(pair_player_id, pair_user_data) player.reputation += GO_NOT_SUCCESS_REPUTATION pair_player.reputation += GO_NOT_SUCCESS_REPUTATION player.update() pair_player.update() buttons = get_general_buttons(user_data, player) bot.send_message(chat_id=player_id, text=first_text + "\nПолучено {}🔘".format(GO_NOT_SUCCESS_REPUTATION), reply_markup=buttons) bot.send_message(chat_id=pair_player_id, text=second_text + "\nПолучено {}🔘".format(GO_NOT_SUCCESS_REPUTATION), reply_markup=buttons) now = datetime.datetime.now(tz=moscow_tz).replace(tzinfo=None) request = "insert into castle_logs(player_id, action, result, date, additional_info) values (%s, %s, %s, %s, %s)" cursor.execute(request, (player.id, quest, 2, now, json.dumps({"result": "two_players_fail", "pair_player_id": pair_player_id}))) cursor.execute(request, (pair_player_id, quest, 2, now, json.dumps({"result": "two_players_fail", "pair_player_id": player.id})))
def request_change_update_message(bot, update, user_data): user_data.update({"status": "editing_update_message"}) buttons = get_general_buttons(user_data) bot.send_message(chat_id=update.message.from_user.id, text="Следующее сообщение будет отображено в башне. Оно должен влезть в это сообщение:\n\n" "{}".format(Location.get_location_enter_text_by_id(5, without_format=True).format( "")), reply_markup=buttons)
def my_cabinet(bot, update, user_data): user_data.update({"status": "my_cabinet"}) response = "Вы входите в свой кабинет. Добро пожаловать. Снова." buttons = get_general_buttons(user_data) bot.send_message(chat_id=update.message.from_user.id, text=response, reply_markup=buttons, parse_mode='HTML')
def request_duty_feedback(bot, update, user_data): """ Функция запроса отправки сообщения стражникам """ user_data.update({"status": "duty_feedback"}) bot.send_message( chat_id=update.message.chat_id, text="Следующее сообщение будет отправлено стражникам на вахте!", reply_markup=get_general_buttons(user_data))
def request_guild_message_notify(bot, update, user_data): """ Функция запроса рассылки по гильдиям """ user_data.update({"status": "sending_guild_message"}) buttons = get_general_buttons(user_data) bot.send_message(chat_id=update.message.from_user.id, text="Следующее сообщение будет разослано во все гильдии", reply_markup=buttons)
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 construction_return(bot, job): cursor = conn.cursor() player_id = job.context[0] user_data = job.context[1] if user_data.get("status") not in ["construction"]: return location_id = user_data.get("construction_id") if location_id is None: bot.send_message(chat_id=player_id, text="Ошибка поиска локации.") return location = Location.get_location(location_id) if location is None: bot.send_message(chat_id=player_id, text="Ошибка поиска локации.") return print(location.name, location.state, location.building_process) if location.state is True or location.building_process < 0: bot.send_message( chat_id=player_id, text= "Локация уже построена или стройка не начиналась. Возможно, локацию " "построили в то время, пока вы добирались до стройки.") return location.building_process += 3 player = Player.get_player(job.context[0]) if location.building_process >= location.need_clicks_to_construct: location.state = True bot.send_message( chat_id=player_id, text="Локация успешно построена! Вы положили последний камень!") player.reputation += 50 - CONSTRUCTION_REPUTATION player.reputation += CONSTRUCTION_REPUTATION player.update_to_database() location.update_location_to_database() user_data.update({"status": "central_square"}) if "construction_id" in user_data: user_data.pop("construction_id") if job.context[0] in construction_jobs: try: construction_jobs.pop(job.context[0]) except Exception: logging.error(traceback.format_exc()) buttons = get_general_buttons(user_data, player) request = "insert into castle_logs(player_id, action, result, additional_info, date) values (%s, %s, %s, %s, %s)" cursor.execute(request, (player.id, "construction", 1, json.dumps({"location_id": location_id}), datetime.datetime.now(tz=moscow_tz).replace(tzinfo=None))) bot.send_message( chat_id=job.context[0], text="Вы вернулись со стройки. Получено <code>{}</code> 🔘".format( CONSTRUCTION_REPUTATION), reply_markup=buttons, parse_mode='HTML')
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 tops(bot, update, user_data, response=""): """ Показ сообщения с топами :param bot: Bot instance :param update: Update instance :param user_data: user_data Dictionary :param response: Строка, к которой будут добавлены топы (позволяет разместить объявление поверх сообщения) :return: None """ user_data.update({"status": "tops"}) buttons = get_general_buttons(user_data) response += "Выберите категорию:" bot.send_message(chat_id=update.message.chat_id, text=response, reply_markup=buttons)
def request_change_castle_message(bot, update, user_data): """ Запрос смены сообщения Короля (на Центральной Площади) """ central = Location.get_location(0) current_message = central.special_info.get("enter_text_format_values") user_data.update({"status": "changing_castle_message"}) buttons = get_general_buttons(user_data) bot.send_message( chat_id=update.message.from_user.id, text= "Текущее сообщение:\n<em>{}</em>\nВведите новое сообщение. Не делайте его слишком большим." "".format(current_message), parse_mode='HTML', reply_markup=buttons)
def request_change_debrief(bot, update, user_data): """ Функция запроса смены дебрифа в Тронном Зале """ user_data.update({"status": "editing_debrief"}) buttons = get_general_buttons(user_data) bot.send_message( chat_id=update.message.from_user.id, text= "Следующее сообщение будет новым дебрифом. Он должен влезть в это сообщение:\n\n" "{}".format( Location.get_location_enter_text_by_id(2, without_format=True).format( "DjedyBreaM", "")), reply_markup=buttons)
def castle_gates(bot, update, user_data): """ Функция, вызываемая при подходе к вратам замка """ location_id = 3 user_data.update({"status": "castle_gates", "location_id": 3}) response = Location.get_location_enter_text_by_id(location_id) player = Player.get_player(update.message.from_user.id) buttons = get_general_buttons(user_data, only_buttons=True, player=player) if player is not None and player.game_class == "Sentinel": # Только для стражей, захардкожено response += "\nКак страж, ты имеешь возможность заступить на вахту\n" reply_markup = ReplyKeyboardMarkup(buttons, resize_keyboard=True) bot.send_message(chat_id=update.message.chat_id, text=response, parse_mode='HTML', reply_markup=reply_markup)
def king_cabinet(bot, update, user_data): """ Функция, вызываемая при входе в кабинет Короля """ response = "Вы входите в свой кабинет. Память услужливо подсказывает вам текущий список генералов:\n" for user_id in high_access_list: player = Player.get_player(user_id, notify_on_error=False) if player is None: continue response += "@{} - <b>{}</b>\nОтправить в ссылку: /remove_general_{}\n" \ "\n".format(player.username, player.nickname, player.id) user_data.update({"status": "king_cabinet"}) buttons = get_general_buttons(user_data) bot.send_message(chat_id=update.message.from_user.id, text=response, reply_markup=buttons, parse_mode='HTML')
def send_duty_feedback(bot, update, user_data): """ Функция отправки сообщения стражникам """ threading.Thread(target=forward_then_reply_to_duty, args=(bot, update.message)).start() user_data.update({"status": "castle_gates"}) reply_markup = get_general_buttons(user_data, player=Player.get_player( update.message.from_user.id)) bot.send_message( chat_id=update.message.from_user.id, text="Вы обратились к стражникам у городских ворот. Ожидайте ответа.", reply_markup=reply_markup) player = Player.get_player(update.message.from_user.id) on_duty_request(player)
def request_mid_feedback(bot, update, user_data): """ Функция запроса обращения в МИД """ mes = update.message if not check_mid_feedback_time_access(bot, update): return loc = Location.get_location(2) banned_users = loc.special_info.get("banned_in_feedback") if mes.from_user.id in banned_users: bot.send_message(chat_id=mes.chat_id, text="Вам запретили общаться здесь!", reply_to_message_id=mes.message_id) return user_data.update({"status": "mid_feedback"}) bot.send_message(chat_id=update.message.chat_id, text="Следующее сообщение будет отправлено в чат мида.", reply_markup=get_general_buttons(user_data))
def player_awaiting_timeout(bot, cur_job): quest, player_id = cur_job.context.get("quest"), cur_job.context.get("player_id") player = Player.get_player(player_id) user_data = dispatcher.user_data.get(player_id) status = user_data.get("status") if status != "waiting_second_player_for_quest": return return_from_quest(player_id, user_data) buttons = get_general_buttons(user_data, player) player.reputation += GO_NOT_SUCCESS_REPUTATION player.update() bot.send_message(chat_id=player_id, text=random.choice(quest_texts[quest]["one_player"]) + "\nПолучено {}🔘".format(GO_NOT_SUCCESS_REPUTATION), reply_markup=buttons) now = datetime.datetime.now(tz=moscow_tz).replace(tzinfo=None) request = "insert into castle_logs(player_id, action, result, date, additional_info) values (%s, %s, %s, %s, %s)" cursor.execute(request, (player.id, quest, 1, now, json.dumps({"result": "one_player_success"})))
def begin_duty(bot, update, user_data): """ Функция начала вахты для игрока (стражника) """ mes = update.message player_id = mes.from_user.id player = Player.get_player(player_id) if player.game_class != 'Sentinel': bot.send_message(chat_id=mes.chat_id, text="Только стражники могут вставать на вахту!") return gates = Location.get_location(3) invite_link = gates.special_info.get("invite_link") if invite_link is None: try: invite_link = bot.exportChatInviteLink(SENTINELS_DUTY_CHAT_ID) if invite_link is not None: invite_link = invite_link[ 22:] # Обрезаю https://t.me/joinchat/ gates.special_info.update({"invite_link": invite_link}) gates.update_location_to_database() except TelegramError: logging.error(traceback.format_exc()) players_on_duty = gates.special_info.get("players_on_duty") if player_id in players_on_duty: bot.send_message(chat_id=mes.chat_id, text="Вы уже на вахте!") else: players_on_duty.append(player_id) gates.update_location_to_database() try: bot.unbanChatMember(chat_id=SENTINELS_DUTY_CHAT_ID, user_id=player_id) except TelegramError: logging.error(traceback.format_exc()) user_data.update({"on_duty": True}) reply_markup = get_general_buttons(user_data) bot.send_message( chat_id=mes.from_user.id, text="Вы заступили на вахту. <a href=\"{}\">Вступайте в чат!</a>" "".format("https://t.me/joinchat/" + invite_link), parse_mode='HTML', reply_markup=reply_markup)
def send_mid_feedback(bot, update, user_data): """ Функция отправки обращения в МИД """ if not check_mid_feedback_time_access(bot, update): return threading.Thread(target=forward_then_reply_to_mid, args=(bot, update.message)).start() user_data.update({"status": "throne_room"}) rp_off = user_data.get("rp_off") if rp_off: user_data.update({"status": DEFAULT_CASTLE_STATUS}) reply_markup = get_general_buttons(user_data) bot.send_message( chat_id=update.message.from_user.id, text= "Ваше обращение к Совету было озвучено. Если оно было по делу, то ожидайте ответа, " "но бойтесь его кары, если это не так!", reply_markup=reply_markup) player = Player.get_player(player_id=update.message.from_user.id) on_mid_request(player)
def end_duty(bot, update, user_data): """ Функция выхода со стражи (раньше кикала игрока из чата) """ mes = update.message player_id = mes.from_user.id player = Player.get_player(player_id) gates = Location.get_location(3) players_on_duty = gates.special_info.get("players_on_duty") if player_id in players_on_duty: players_on_duty.remove(player_id) gates.update_location_to_database() if "on_duty" in user_data: user_data.pop("on_duty") reply_markup = get_general_buttons(user_data, player=player) try: pass # bot.kickChatMember(chat_id=SENTINELS_DUTY_CHAT_ID, user_id=player_id) except TelegramError: logging.error(traceback.format_exc()) bot.send_message(chat_id=mes.from_user.id, text="Вы успешно покинули вахту. Спасибо за службу!", reply_markup=reply_markup)
def manuscript(bot, update, user_data): user_data.update({"status": "manuscript"}) buttons = get_general_buttons(user_data) bot.send_message(chat_id=update.message.from_user.id, text="Перед вами находится манускрипт. Выберите раздел:", reply_markup=buttons)
def place_roulette_bet(bot, update, user_data): """ Функция осуществления ставки в рулетке """ mes = update.message bet = re.search("(\\d+)", mes.text) if bet is None: bot.send_message( chat_id=mes.chat_id, text="Неверный синтаксис. Пожалуйста, пришлите в ответ целое число " "не меньше 10") return bet = int(bet.group(1)) if bet < 10: bot.send_message(chat_id=mes.chat_id, text="Минимальная ставка: 10🔘.") return player = Player.get_player(mes.from_user.id) if player is None: return if bet > player.reputation: bot.send_message(chat_id=mes.chat_id, text="У вас не хватает 🔘жетонов!") return roulette = Location.get_location(10) if roulette.special_info.get("game_running"): bot.send_message(chat_id=mes.chat_id, text="Игра началась. Ставки закрыты!") return placed = roulette.special_info["placed"].get(str(mes.from_user.id)) if placed is None: placed = 0 placed += bet now = datetime.datetime.now(tz=moscow_tz).replace(tzinfo=None).time() if now < datetime.time(hour=ROULETTE_HOUR_LIMIT) or now > datetime.time( hour=ROULETTE_LAST_GAME_HOUR): if placed > ROULETTE_MAX_BET_LIMIT: bot.send_message( chat_id=mes.chat_id, text="Максимальная ставка: <b>{}</b>🔘.\n" "На последнюю игру каждые сутки ставки не ограничены.".format( ROULETTE_MAX_BET_LIMIT), parse_mode='HTML') return player.reputation -= bet player.update() roulette.special_info["placed"].update({str(mes.from_user.id): placed}) total_placed = roulette.special_info["total_placed"] if total_placed is None: total_placed = 0 total_placed += bet roulette.special_info["total_placed"] = total_placed roulette.special_info["enter_text_format_values"] = [ total_placed ] # Если изменится вид сообщения, поменять roulette.update_location_to_database() user_data.update({"status": "roulette"}) buttons = get_general_buttons(user_data, player=player) bot.send_message( chat_id=mes.from_user.id, text= "Ставка успешно сделана. Удачи на игре!\n\nРезультаты будут на <a href=" "\"https://t.me/joinchat/DdKE7kUfsmDVIC2DJymw_A\">⛲️Центральной площади</a>", reply_markup=buttons, parse_mode='HTML')
def send_bot_guild_message_notify(bot, update, user_data): user_data.update({"status": "my_cabinet"}) do_mailing(bot, update.message.text) bot.send_message(update.message.from_user.id, text="Успешно отправлено!", reply_markup=get_general_buttons(user_data))