async def bot_help(event: events.NewMessage.Event) -> None: args = event.pattern_match.group(4) try: assert args args = args.lower() for game_bot in GAME_BOTS: if game_bot.HELP_REGEX.match(args): await event.respond(game_bot.HELP_MSG, link_preview=False) break else: raise AssertionError except AssertionError: event.reply("This is not a valid game.")
async def start_handler(cls, event: events.NewMessage.Event) -> None: try: player_names = [n[4:-5] for n in event.raw_text.split("\n\n")[1].split("\n")[1:] if n[1] == "🔵"] player_names_with_usernames = [e[1] for e in event.get_entities_text(MessageEntityTextUrl)] if len(player_names) != len(player_names_with_usernames): await cls.error_handler(event, "start_no_username", player_names, player_names_with_usernames) return cls.players = [await client.get_entity(e[0].url) for e in event.get_entities_text(MessageEntityTextUrl)] except ValueError as e: match = USERNAME_NOT_EXIST_MSG.match(str(e)) if match: await cls.error_handler(event, f"@{match.group(1)}") else: raise
async def place_handler(cls, event: events.NewMessage.Event) -> None: text = event.raw_text user_ids = [e[0].user_id for e in event.get_entities_text(MessageEntityMentionName)] if "\n" * 3 in text: # The message contains 2 places, deal them one by one li = text.split("\n\n\n") n = li[0].count("\n") cls.place_handler2(li[0], user_ids[:n]) cls.place_handler2(li[1], user_ids[n:]) else: cls.place_handler2(text, user_ids)
async def end_handler(cls, event: events.NewMessage.Event): players = [mention_markdown(await client.get_entity(PeerUser(p[0].url))) if isinstance(p[0], MessageEntityTextUrl) else f"**{p[1]}**" for p in [e for e in event.get_entities_text() if isinstance(e[0], (MessageEntityBold, MessageEntityTextUrl))]] base_score = 1 if len(players) < 6 else 1 res = tuple(zip(players, [True if line[-1] == "贏" else False for line in event.raw_text.split("\n\n\n")[0].split("\n")])) results = {"won": [p[0] for p in res if p[1]], "lost": [p[0] for p in res if not p[1]]} to_send = f"呢場狼人玩完咗啦。\n\n呢局有{len(players)}個玩家,你哋每人至少會獲得{base_score}參與分。"
def my_handler(event: events.NewMessage.Event): global recent_reacts # This utils function gets the unique identifier from peers (to_id) to_id = utils.get_peer_id(event.message.to_id) # Through event.raw_text we access the text of messages without format words = re.split('\W+', event.raw_text) # Try to match some reaction for trigger, response in REACTS.items(): if len(recent_reacts[to_id]) > 3: # Silently ignore triggers if we've recently sent 3 reactions break if trigger in words: # Remove recent replies older than 10 minutes recent_reacts[to_id] = [ a for a in recent_reacts[to_id] if datetime.now() - a < timedelta(minutes=10) ] # Send a reaction as a reply (otherwise, event.respond()) event.reply(response) # Add this reaction to the list of recent actions recent_reacts[to_id].append(datetime.now()) # Automatically send relevant media when we say certain things # When invoking requests, get_input_entity needs to be called manually if event.out: if event.raw_text.lower() == 'x files theme': client.send_voice_note(event.message.to_id, 'xfiles.m4a', reply_to=event.message.id) if event.raw_text.lower() == 'anytime': client.send_file(event.message.to_id, 'anytime.png', reply_to=event.message.id) if '.shrug' in event.text: event.edit(event.text.replace('.shrug', r'¯\_(ツ)_/¯'))
async def end_handler(cls, event: events.NewMessage.Event) -> None: try: urls = event.get_entities_text(MessageEntityTextUrl) if cls.nobody_won_check(event): await cls.end_handler2() elif cls.bot_won_check(event): await cls.end_handler2(bot_won=True) else: await cls.end_handler2(await client.get_entity(urls[-1][0].url)) except ValueError as e: match = USERNAME_NOT_EXIST_MSG.match(str(e)) if match: await cls.error_handler(event, f"@{match.group(1)}") else: raise
async def end_handler(cls, event: events.NewMessage.Event) -> None: entities = event.get_entities_text(MessageEntityMentionName) players = [await client.get_entity(PeerUser(e[0].user_id)) for e in entities] res = tuple(zip(players, [True if line == "贏" else False for line in [line[-1] for line in event.raw_text.split("\n\n")[0].split("\n")[1:]]])) results = {"won": [p[0] for p in res if p[1]], "lost": [p[0] for p in res if not p[1]]} base_score = 1 if len(players) < 8 else 2 if len(players) < 11 else 3 to_send = f"呢場狼人玩完咗啦。\n\n呢局有{len(players)}個玩家,你哋每人至少會獲得{base_score}參與分。" for result in "won", "lost": if results[result]: to_send += f"\n\n{'勝出' if result == 'won' else '其餘' if results['won'] else '參與'}玩家:" for player in results[result]: to_send += f"\n{mention_markdown(player)}: +{base_score + (2 if result == 'won' else 0)}分" if player.id in cls.afk_messages: to_send += f" [AFK]({cls.afk_messages[player.id]})" to_send += (f"\n\n由於狼人計分制度複雜,以及本bot難以辨認大愛同Betrayal等行爲,{JS_MENTION}稍後可能會修改本局玩家" "分數甚至警告違規玩家。\n\n#DC2 #DC2Werewolf #DC2Manual\n") to_send += "".join([f"\n#DC2P{e[0].user_id}" for e in entities]) await bot.send_message(HK_DUKER, to_send) cls.reset_game()
async def afk_handler(cls, event: events.NewMessage.Event) -> None: entities = event.get_entities_text(MessageEntityMentionName)[:-2:3] # exclude lynch res (2 mentions, sep) for user_id in [e[0].user_id for e in entities]: cls.afk_messages[user_id] = f"{cls.GROUP_LINK}/{event.id}" # save msg link for end handler
def bot_won_check(cls, event: events.NewMessage.Event) -> bool: bold_entities = event.get_entities_text(MessageEntityBold) try: return bold_entities and bold_entities[-1][0].offset > event.raw_text.index("完~!\n") except IndexError: return False
def nobody_won_check(cls, event: events.NewMessage.Event) -> bool: entities = [e for e in event.get_entities_text() if isinstance(e[0], (MessageEntityBold, MessageEntityTextUrl))] try: return entities and entities[-1][0].offset > event.raw_text.index("完~!\n") except IndexError: return False
async def afk_handler(cls, event: events.NewMessage.Event) -> None: afk_player_username = event.get_entities_text(MessageEntityTextUrl)[0][0].url[13:] # [13:] gets username for nub in [p for p in cls.players if p.username == afk_player_username]: cls.afk_players_ids.append(nub.id)