def update_combo(universal_id: str, message: str, combo: int) -> bool: """Update the current combo according to the message.""" msg_base = load(universal_id, 'current_msg_base') left_increment = load(universal_id, 'current_left_increment') right_increment = load(universal_id, 'current_right_increment') if not msg_base: msg_base = message if combo <= 1: place = message.find(msg_base) left_increment = message[:place] right_increment = message[place + len(msg_base):] msg_append = combo * left_increment + msg_base + combo * right_increment if message == msg_append: save(universal_id, 'current_msg_base', msg_base) save(universal_id, 'current_left_increment', left_increment) save(universal_id, 'current_right_increment', right_increment) return combo + 1 else: save(universal_id, 'current_msg_base', message) save(universal_id, 'current_left_increment', '') save(universal_id, 'current_right_increment', '') return 1
def _load_daily_star(uid: str) -> list: """Load the daily star from database.""" star_db = load('0', 'dailystar') try: return star_db[uid] except Exception: return []
def _initialize_subscribed_list(universal_id: str, _type: str): """Initialize the subscribed list.""" subscribed_list = load(universal_id, _type) if not subscribed_list: subscribed_list = {} save(universal_id, _type, subscribed_list) return subscribed_list
async def subscriber_update(bot: Bot, event: Event, state: dict): """Handle the subscribe command.""" universal_id = str(event.self_id) + str(event.group_id) subscribed_list = load(universal_id, 'subscribed_list') if not subscribed_list: subscribed_list = {} save(universal_id, 'subscribed_list', subscribed_list) operation = { '+': lambda x: subscribed_list.setdefault(x, False), '-': lambda x: subscribed_list.pop(x), } arg = str(event.message).strip() try: operator = arg[0] if operator == 'o': await bot.send(event=event, message='当前订阅用户B站UID名单: %s' % ', '.join(subscribed_list.keys())) return operand = str(int(arg[1:].strip())) operation[operator](operand) # add or remove the word save(universal_id, 'subscribed_list', subscribed_list) await bot.send(event=event, message='订阅用户信息更新成功~') except Exception: logger.error(traceback.format_exc()) await bot.send(event=event, message='订阅用户信息更新失败,请检查日志文件~')
async def show_my_info(bot: Bot, event: Event, state: dict): """Handle the id_me command.""" universal_id = str(event.self_id) + str(event.group_id) user_id = f'{event.user_id}' try: members = load(universal_id, 'members') uid = int(members[user_id]['id']) except Exception: await bot.send(event=event, message='个人信息获取失败,请检查头衔~') return colding_time = _validate_id(universal_id, str(uid), gap=3600) if colding_time > 0: wait_message = '用户ID[%d]尚在查询冷却期,剩余冷却时间%d秒~' % (uid, colding_time) await bot.send(event=event, message=wait_message) return try: user_info = await get_user_info(uid) except Exception: logger.error(traceback.format_exc()) await bot.send(event=event, message='用户信息获取失败~') return user_info_message = format_user_info(user_info) await bot.send(event=event, message=user_info_message)
def format_level_list(level_list_data: dict) -> str: """Format the user level info data.""" data = _initialize_history() for val in level_list_data: data[level_ref[val['level']]] = val['count'] line = ['等级: 当前 | 合计'] total, history_total = 0, 0 level_list_history = load('0', 'level_history') if not level_list_history: level_list_history = [] level_history = _initialize_history() for val in level_list_history: level_history[level_ref[val['level']]] = val['count'] for lv in range(max_level, min_level - 1, -1): ref = level_ref[lv] # global reference total += data[ref] history_total += level_history[ref] line.append('%s: %d(%+d) | %d(%+d)' % (ref, data[ref], data[ref] - level_history[ref], total, total - history_total)) result_message = '' for each_line in line: result_message = result_message + each_line + '\n' return result_message.strip()
async def update_group_members(bot: Bot, group_id: str): """Update group members' information and store it to the database.""" logger.info('Updating group [%s] members ...' % group_id) universal_id = str(bot.self_id) + str(group_id) # load the original information from the database members = load(universal_id, 'members') if not members: members = {} group_members_list = await bot.get_group_member_list(group_id=group_id) for member in group_members_list: group_member_info = await bot.get_group_member_info( group_id=group_id, user_id=member['user_id'], no_cache=True) user_id = str(group_member_info['user_id']) if user_id not in members: # update the user information from the remote server members[user_id] = {} members[user_id]['id'] = group_member_info['title'] members[user_id]['nickname'] = group_member_info['nickname'] members[user_id]['card'] = group_member_info['card'] for user_id in members: # generate locally stored information members[user_id].setdefault('42score', 0) members[user_id].setdefault('42score_daily', 0) # save the updated information to the database save(universal_id, 'members', members)
async def show_repeater_status(bot: Bot, event: Event, state: dict): """Print the status of the repeater.""" universal_id = str(event.self_id) + str(event.group_id) msg_base = load(universal_id, 'current_msg_base') left_increment = load(universal_id, 'current_left_increment') right_increment = load(universal_id, 'current_right_increment') combo = load(universal_id, 'current_combo') mutate_prob = load(universal_id, 'mutate_probability') cut_in_prob = load(universal_id, 'cut_in_probability') block_wordlist = load(universal_id, 'block_wordlist') if not combo: combo = 0 if not mutate_prob: mutate_prob = 5 if not cut_in_prob: cut_in_prob = 5 block_message = '空' if not block_wordlist else ', '.join(block_wordlist) message = '复读状态: [%d]-[%s|%s|%s]-[%d%%|%d%%]\n当前屏蔽词: %s' % ( combo, left_increment, msg_base, right_increment, mutate_prob, cut_in_prob, block_message) await bot.send(event=event, message=message)
async def say_goodbye_on_leaving(bot: Bot, event: Event, state: dict): """Handle the say_goodbye command. Admin privilege required.""" universal_id = str(event.self_id) + str(event.group_id) leave_id = f'{event.user_id}' members = load(universal_id, 'members') uid = members[leave_id][ 'id'] if leave_id in members and members[leave_id]['id'] else '未知' if event.user_id != event.self_id: # the bot can not respond to itself await bot.send(event=event, message='有群员[Id: %s]跑路了QAQ' % uid)
def check_block_wordlist(universal_id: str, message: str) -> bool: """Check whether the message contains blocked words.""" block_wordlist = load(universal_id, 'block_wordlist') if not block_wordlist: block_wordlist = set() for w in block_wordlist: if w in message: return True # the message contains blocked words return False # the message does not contain blocked words
def get_repeated_message(universal_id: str) -> str: """Get repeated message and add some variations on it.""" msg_base = load(universal_id, 'current_msg_base') left_increment = load(universal_id, 'current_left_increment') right_increment = load(universal_id, 'current_right_increment') combo = load(universal_id, 'current_combo') mutate_prob = load(universal_id, 'mutate_probability') if not mutate_prob: mutate_prob = 5 save(universal_id, 'mutate_probability', mutate_prob) cut_in_prob = load(universal_id, 'cut_in_probability') if not cut_in_prob: cut_in_prob = 5 save(universal_id, 'cut_in_probability', cut_in_prob) if random.randint(1, 100) <= cut_in_prob: # reset the combo counter here save(universal_id, 'current_combo', 0) return exclaim_msg('打断' * (msg_base[0:2] == '打断'), '4', True, 1) final = combo * left_increment + msg_base + combo * right_increment can_mutate = random.randint(1, 100) <= mutate_prob # add combo for self repetition if the message is not mutated save(universal_id, 'current_combo', (combo + 1) * (not can_mutate)) return mutate_msg(final, mutate=can_mutate)
def _validate_id(universal_id: str, uid: str, gap: int) -> int: """Add id into colding list.""" current = load(universal_id, 'id_colding_list') if not current: current = {} current_time = int(time.time()) if uid not in current or current_time - current[uid] >= gap: current[uid] = current_time save(universal_id, 'id_colding_list', current) return 0 else: return gap - current_time + current[uid]
def _save_daily_star(uid: str): """Save the daily star into database.""" today = time.strftime('%Y-%m-%d', time.localtime()) star_db = load('0', 'dailystar') if not star_db: star_db = {} star_db.setdefault(uid, []) if today not in star_db[uid]: star_db[uid].append(today) save('0', 'dailystar', star_db)
async def show_poke_greet(bot: Bot, event: Event, state: dict): """Greet the person when the bot is poked, and repeat the poke action.""" if event.target_id == event.self_id and event.sender_id != event.self_id: # ensure poking target await show_greet(bot, event, state) universal_id = str(event.self_id) + str(event.group_id) poke_combo = load(universal_id, 'current_poke_combo') if not poke_combo: poke_combo = 0 # initialization for current poke combo poke_target = load(universal_id, 'current_poke_target') if not poke_target: poke_target = -1 poke_combo = poke_combo + 1 - poke_combo * (poke_target != event.target_id) if poke_combo == 5: poke_combo += 1 await bot.send(event=event, message=slim_msg('[CQ:poke,qq=%d]' % poke_target)) save(universal_id, 'current_poke_combo', poke_combo) save(universal_id, 'current_poke_target', event.target_id)
async def repeat(bot: Bot, event: Event, state: dict): """Handle the repeat command.""" message = str(slim_msg(event.message)).strip() universal_id = str(event.self_id) + str(event.group_id) # get current combo for repetition combo = load(universal_id, 'current_combo') if not combo: combo = 0 # initialization for current combo if check_block_wordlist(universal_id, message): return combo = update_combo(universal_id, message, combo) save(universal_id, 'current_combo', combo) if combo == 5: repeated_message = get_repeated_message(universal_id) await bot.send(event=event, message=repeated_message)
async def say_hello_on_entering(bot: Bot, event: Event, state: dict): """Handle the say_hello command.""" universal_id = str(event.self_id) + str(event.group_id) join_id = f'{event.user_id}' members = load(universal_id, 'members') if event.user_id == event.self_id: # the bot can not respond to itself return if join_id in members: # this means the user has been a group member before await bot.send(event=event, message='欢迎大佬回归,希望大佬天天破pb~') return # preserve former information await bot.send(event=event, message='欢迎大佬,希望大佬天天破pb~') # Creating a new user try: await update_group_members(bot, event.group_id) except Exception: logger.error(traceback.format_exc())
async def update_block_word(bot: Bot, event: Event, state: dict): """Handle the blockword command.""" universal_id = str(event.self_id) + str(event.group_id) wordlist = load(universal_id, 'block_wordlist') wordlist = set(wordlist) if wordlist else set() operation = { '+': lambda x: wordlist.add(x), '-': lambda x: wordlist.remove(x), } arg = str(event.message).strip() operator = arg[0] operand = arg[1:].strip() try: operation[operator](operand) # add or remove the word save(universal_id, 'block_wordlist', list(wordlist)) await bot.send(event=event, message='复读屏蔽词更新成功~') except Exception: logger.error(traceback.format_exc()) await bot.send(event=event, message='复读屏蔽词更新失败,请检查日志文件~')
def __init__(self, universal_id: str): """Initialize the member database in a certain group with a certain bot.""" self.universal_id = universal_id self.members = load(self.universal_id, 'members')