async def description_guess_group_ranking(bot, ev: CQEvent): ranking = gm.db.get_ranking(ev.group_id) msg = ["【猜头像小游戏排行榜】"] for i, item in enumerate(ranking): uid, count = item m = await bot.get_group_member_info( self_id=ev.self_id, group_id=ev.group_id, user_id=uid ) name = util.filt_message(m["card"]) or util.filt_message(m["nickname"]) or str(uid) msg.append(f"第{i + 1}名:{name} 猜对{count}次") await bot.send(ev, "\n".join(msg))
async def decherulize(bot, ev: CQEvent): s = ev.message.extract_plain_text() if len(s) > 1501: await bot.send(ev, '切、切噜太长切不动勒切噜噜...', at_sender=True) return msg = '的切噜噜是:\n' + util.filt_message(util.escape(cheru2str(s))) await bot.send(ev, msg, at_sender=True)
async def whois(bot, ev: CQEvent): name = ev.message.extract_plain_text().strip() if not name: return id_ = chara.name2id(name) confi = 100 guess = False if id_ == chara.UNKNOWN: id_, guess_name, confi = chara.guess_id(name) guess = True c = chara.fromid(id_) if confi < 60: return uid = ev.user_id if not lmt.check(uid): await bot.finish(ev, f'兰德索尔花名册冷却中(剩余 {int(lmt.left_time(uid)) + 1}秒)', at_sender=True) lmt.start_cd(uid, 120 if guess else 0) if guess: name = filt_message(name) msg = f'兰德索尔似乎没有叫"{name}"的人...\n角色别称补全计划: github.com/Ice-Cirno/HoshinoBot/issues/5' await bot.send(ev, msg) msg = f'您有{confi}%的可能在找{guess_name} {c.icon.cqcode} {c.name}' await bot.send(ev, msg) else: msg = f'{c.icon.cqcode} {c.name}' await bot.send(ev, msg, at_sender=True)
async def switch_service(session: CommandSession, turn_on: bool): action_tip = '启用' if turn_on else '禁用' if session.ctx['message_type'] == 'group': names = session.current_arg_text.split() if not names: session.finish(f"空格后接要{action_tip}的服务名", at_sender=True) group_id = session.ctx['group_id'] svs = Service.get_loaded_services() succ, notfound = [], [] for name in names: if name in svs: sv = svs[name] u_priv = priv.get_user_priv(session.ctx) if u_priv >= sv.manage_priv: sv.set_enable(group_id) if turn_on else sv.set_disable( group_id) succ.append(name) else: try: await session.send( f'权限不足!{action_tip}{name}需要:{sv.manage_priv},您的:{u_priv}\n{PRIV_TIP}', at_sender=True) except: pass else: notfound.append(util.filt_message(name)) msg = [] if succ: msg.append(f'已{action_tip}服务:' + ', '.join(succ)) if notfound: msg.append('未找到服务:' + ', '.join(notfound)) if msg: session.finish('\n'.join(msg), at_sender=True) else: if session.ctx['user_id'] not in session.bot.config.SUPERUSERS: return args = session.current_arg_text.split() if len(args) < 2: session.finish( 'Usage: <service_name> <group_id1> [<group_id2>, ...]') name, *group_ids = args svs = Service.get_loaded_services() if name not in svs: session.finish(f'未找到服务:{name}') sv = svs[name] succ = [] for gid in group_ids: try: gid = int(gid) sv.set_enable(gid) if turn_on else sv.set_disable(gid) succ.append(gid) except: try: await session.send(f'非法群号:{gid}') except: pass session.finish(f'服务{name}已于{len(succ)}个群内{action_tip}:{succ}')
async def anti_msg_recall(session: NoticeSession): uid = session.event.user_id if uid == session.event.operator_id: data = await session.bot.get_msg(self_id=session.event.self_id, message_id=session.event.message_id) cardname = data.get('sender', {}).get('card') nickname = data.get('sender', {}).get('nickname') name = cardname or nickname or uid msg = data.get('message') msg = util.filt_message(Message(msg)) if msg: await session.send(f'{name}({uid})撤回了:\n{msg}')
async def leave_notice(session: NoticeSession): ev = session.event name = ev.user_id if ev.user_id == ev.self_id: return try: info = await session.bot.get_stranger_info(self_id=ev.self_id, user_id=ev.user_id) name = info['nickname'] or name name = util.filt_message(name) except CQHttpError as e: sv1.logger.exception(e) await session.send(f"{name}({ev.user_id})退群了。")
async def add_member(bot:NoneBot, ctx:Context_T, args:ParseResult): bm = BattleMaster(ctx['group_id']) clan = _check_clan(bm) uid = args['@'] or args.at or ctx['user_id'] name = args[''] if uid != ctx['user_id']: _check_admin(ctx, '才能添加其他人') try: # 尝试获取群员信息,用以检查该成员是否在群中 await bot.get_group_member_info(self_id=ctx['self_id'], group_id=bm.group, user_id=uid) except: raise NotFoundError(f'Error: 无法获取群员信息,请检查{uid}是否属于本群') if not name: m = await bot.get_group_member_info(self_id=ctx['self_id'], group_id=bm.group, user_id=uid) name = util.filt_message(m['card']) or util.filt_message(m['nickname']) or str(m['user_id']) mem = bm.get_member(uid, bm.group) or bm.get_member(uid, 0) # 兼容cmdv1 if mem: bm.mod_member(uid, mem['alt'], name, 1) await bot.send(ctx, f'成员{ms.at(uid)}昵称已修改为{name}') else: bm.add_member(uid, bm.group, name, 1) await bot.send(ctx, f"成员{ms.at(uid)}添加成功!欢迎{name}加入{clan['name']}")
def parse(self, args: List[str], message: Message) -> ParseResult: result = ParseResult() # 解析参数,以一个字符开头,或无前缀 for arg in args: name, x = arg[0].upper(), arg[1:] if name in self.arg_dict: holder = self.arg_dict[name] elif '' in self.arg_dict: holder = self.arg_dict[''] name, x = '', arg else: raise ParseError('命令含有未知参数', self.usage) try: if holder.type == str: result.setdefault(name, filt_message(holder.type(x))) else: result.setdefault(name, holder.type(x)) # 多个参数只取第1个 except ParseError as e: e.append(self.usage) raise e except Exception: msg = f"请给出正确的{holder.tip or '参数'}" if name: msg += f"以{name}开头" raise ParseError(msg, self.usage) # 检查所有参数是否以赋值 for name, holder in self.arg_dict.items(): if name not in result: if holder.default is None: # 缺失必要参数 抛异常 msg = f"请给出{holder.tip or '缺少的参数'}" if name: msg += f"以{name}开头" raise ParseError(msg, self.usage) else: result[name] = holder.default # 解析Message内的at result['at'] = 0 for seg in message: if seg.type == 'at': result['at'] = int(seg.data['qq']) return result
async def random_repeater(bot, ev: CQEvent): group_id = ev.group_id msg = str(ev.message) if group_id not in group_stat: group_stat[group_id] = (msg, False, 0) return last_msg, is_repeated, p = group_stat[group_id] if last_msg == msg: # 群友正在复读 if not is_repeated: # 机器人尚未复读过,开始测试复读 if random.random() < p: # 概率测试通过,复读并设flag try: group_stat[group_id] = (msg, True, 0) await bot.send(ev, util.filt_message(ev.message)) except CQHttpError as e: hoshino.logger.error(f'复读失败: {type(e)}') hoshino.logger.exception(e) else: # 概率测试失败,蓄力 p = 1 - (1 - p) / PROB_A group_stat[group_id] = (msg, False, p) else: # 不是复读,重置 group_stat[group_id] = (msg, False, 0)
async def kc_marriage(bot, ev: CQEvent): wife = filt_message(ev.message.extract_plain_text().strip()) tip = f'与{wife}的ケッコンカッコカリ结果是:' if wife else '的ケッコンカッコカリ结果是:' await do_dice(bot, ev, 1, 3, 6, 1, 0, tip)
async def _arena_query(bot, ev: CQEvent, region: int): arena.refresh_quick_key_dic() uid = ev.user_id if not lmt.check(uid): await bot.finish(ev, '您查询得过于频繁,请稍等片刻', at_sender=True) lmt.start_cd(uid) # 处理输入数据 defen = ev.message.extract_plain_text() defen = re.sub(r'[??,,_]', '', defen) defen, unknown = chara.roster.parse_team(defen) if unknown: _, name, score = chara.guess_id(unknown) if score < 70 and not defen: return # 忽略无关对话 unknown = filt_message(unknown) msg = f'无法识别"{unknown}"' if score < 70 else f'无法识别"{unknown}" 您说的有{score}%可能是{name}' await bot.finish(ev, msg) if not defen: await bot.finish(ev, '查询请发送"怎么拆+防守队伍",无需+号', at_sender=True) if len(defen) > 5: await bot.finish(ev, '编队不能多于5名角色', at_sender=True) if len(defen) < 5: await bot.finish(ev, '由于数据库限制,少于5名角色的检索条件请移步pcrdfans.com进行查询', at_sender=True) if len(defen) != len(set(defen)): await bot.finish(ev, '编队中含重复角色', at_sender=True) if any(chara.is_npc(i) for i in defen): await bot.finish(ev, '编队中含未实装角色', at_sender=True) if 1004 in defen: await bot.send(ev, '\n⚠️您正在查询普通版炸弹人\n※万圣版可用万圣炸弹人/瓜炸等别称', at_sender=True) # 执行查询 sv.logger.info('Doing query...') res = None try: res = await arena.do_query(defen, uid, region) except hoshino.aiorequests.HTTPError as e: code = e.response["code"] if code == 117 or code == -429: await bot.finish(ev, "高峰期服务器限流!请前往pcrdfans.com/battle") else: await bot.finish(ev, f'code{code} 查询出错,请联系维护组调教\n请先前往pcrdfans.com进行查询', at_sender=True) sv.logger.info('Got response!') # 处理查询结果 if res is None: await bot.finish(ev, '数据库未返回数据,请再次尝试查询或前往pcrdfans.com', at_sender=True) if not len(res): await bot.finish( ev, '抱歉没有查询到解法\n※没有作业说明随便拆 发挥你的想象力~★\n作业上传请前往pcrdfans.com', at_sender=True) res = res[:min(6, len(res))] # 限制显示数量,截断结果 # 发送回复 sv.logger.info('Arena generating picture...') teams = render_atk_def_teams(res) teams = pic2b64(teams) teams = MessageSegment.image(teams) sv.logger.info('Arena picture ready!') # 纯文字版 # atk_team = '\n'.join(map(lambda entry: ' '.join(map(lambda x: f"{x.name}{x.star if x.star else ''}{'专' if x.equip else ''}" , entry['atk'])) , res)) # details = [" ".join([ # f"赞{e['up']}+{e['my_up']}" if e['my_up'] else f"赞{e['up']}", # f"踩{e['down']}+{e['my_down']}" if e['my_down'] else f"踩{e['down']}", # e['qkey'], # "你赞过" if e['user_like'] > 0 else "你踩过" if e['user_like'] < 0 else "" # ]) for e in res] defen = [chara.fromid(x).name for x in defen] defen = f"防守方【{' '.join(defen)}】" at = str(MessageSegment.at(ev.user_id)) msg = [ defen, # at, f'已为骑士{at}查询到以下进攻方案:', str(teams), # '作业评价:', # *details, # '※发送"点赞/点踩"可进行评价' ] if region == 1: msg.append('※使用"b怎么拆"或"台怎么拆"可按服过滤') msg.append('Support by pcrdfans_com') sv.logger.debug('Arena sending result...') await bot.send(ev, '\n'.join(msg)) sv.logger.debug('Arena result sent!') if ev.group_id == 1017321923: await silence(ev, 5 * 60)