async def on_query_arena_all(bot, ev): global binds, lck robj = ev['match'] id = robj.group(1) uid = str(ev['user_id']) async with lck: if id == None: if not uid in binds: await bot.finish(ev, '您还未绑定竞技场', at_sender=True) return else: id = binds[uid]['id'] try: res = await query(id) sv.logger.info('开始生成竞技场查询图片...') # 通过log显示信息 # result_image = await generate_info_pic(res, cx) result_image = await generate_info_pic(res, uid) result_image = pic2b64(result_image) # 转base64发送,不用将图片存本地 result_image = MessageSegment.image(result_image) result_support = await generate_support_pic(res, uid) result_support = pic2b64(result_support) # 转base64发送,不用将图片存本地 result_support = MessageSegment.image(result_support) sv.logger.info('竞技场查询图片已准备完毕!') try: await bot.finish(ev, f"\n{str(result_image)}\n{result_support}", at_sender=True) except Exception as e: sv.logger.info("do nothing") except ApiException as e: await bot.finish(ev, f'查询出错,{e}', at_sender=True)
async def neurasthenia_game(bot, ev: CQEvent): if gm.is_playing(ev.group_id): await bot.finish(ev, "游戏仍在进行中…") with gm.start_game(ev.group_id) as game: chosen_ids = random.sample(game_util.VALID_IDS, TOTAL_PIC_NUM // 2) chosen_ids.extend(chosen_ids) random.shuffle(chosen_ids) # 记忆阶段 await bot.send(ev, f'记忆阶段: ({SHOW_TIME}s后我会撤回图片哦~)') pic = MessageSegment.image(util.pic2b64(game_util.generate_full_pic(ROW_NUM, COL_NUM, chosen_ids))) msg = await bot.send(ev, pic) await asyncio.sleep(SHOW_TIME) await bot.delete_msg(message_id=msg['message_id']) await asyncio.sleep(2) # 回答阶段 displayed_sub_pic_index = random.randint(0, TOTAL_PIC_NUM - 1) chosen_id = chosen_ids[displayed_sub_pic_index] explanation = game_util.EXPLANATION[chosen_id] ids = [game_util.JUMP_ID if i != displayed_sub_pic_index else id for i, id in enumerate(chosen_ids)] pic = MessageSegment.image(util.pic2b64(game_util.generate_full_pic(ROW_NUM, COL_NUM, ids, True))) await bot.send(ev, f'请告诉我另一个"{explanation}"所在位置的编号~ ({ANSWER_TIME}s后公布答案){pic}') game.answer = [i for i, id in enumerate(chosen_ids) if i != displayed_sub_pic_index and id == chosen_id][0] + 1 await asyncio.sleep(ANSWER_TIME) # 结算 game.update_score() msg_part1 = f'{MessageSegment.at(game.winner[0])}首先答对,真厉害~ 加2分! 当前总分为{game.get_first_winner_score()}分' if game.winner else '' msg_part2 = f'{game_util.generate_at_message_segment(game.winner[1:])}也答对了, 加1分~' if game.winner[1:] else '' msg_part3 = f'{game_util.generate_at_message_segment(game.loser)}答错了, 扣1分o(╥﹏╥)o' if game.loser else '' msg_part4 = '咦, 这轮游戏没人参与, 看来题目可能有点难...' if not (msg_part1 or msg_part2 or msg_part3) else "" msg_part = '\n'.join([s for s in [msg_part1, msg_part2, msg_part3, msg_part4] if s]) await bot.send(ev, f'正确答案是: {game.answer}{MessageSegment.image(util.pic2b64(game_util.generate_full_pic(ROW_NUM, COL_NUM, chosen_ids)))}{msg_part}')
async def friend(bot, ev: CQEvent): # 定义非管理员的冷却时间 # if ev.user_id not in bot.config.SUPERUSERS: # if not _flmt.check(ev.user_id): # return # _flmt.start_cd(ev.user_id) data = load_config(os.path.join(os.path.dirname(__file__), 'config.json'))['friend'] arr = [] is_at = False for m in ev.message: if m.type == 'at' and m.data['qq'] != 'all': arr = [int(m.data['qq'])] sid = int(m.data['qq']) is_at = True if not is_at: try: arr = data[f'{ev.group_id}'] except: member_list = await bot.get_group_member_list(self_id=ev.self_id, group_id=ev.group_id) for member in member_list: arr.append(member['user_id']) sid = choice(arr) info = await bot.get_group_member_info(group_id=ev.group_id, user_id=sid, no_cache=True) name = info['card'] or info['nickname'] match = ev['match'] msg = match.group('kw') msg = msg.replace('他', '我').replace('她', '我') image = Image.open(BytesIO(get_pic(sid))) img_origin = Image.new('RGBA', (100, 100), (255, 255, 255)) scale = 3 # 使用新的半径构建alpha层 r = 100 * scale alpha_layer = Image.new('L', (r, r), 0) draw = ImageDraw.Draw(alpha_layer) draw.ellipse((0, 0, r, r), fill=255) # 使用ANTIALIAS采样器缩小图像 alpha_layer = alpha_layer.resize((100, 100), Image.ANTIALIAS) img_origin.paste(image, (0, 0), alpha_layer) # 创建Font对象: font = ImageFont.truetype( os.path.join(os.path.dirname(__file__), 'simhei.ttf'), 30) font2 = ImageFont.truetype( os.path.join(os.path.dirname(__file__), 'simhei.ttf'), 25) # 创建Draw对象: image_text = Image.new('RGB', (450, 150), (255, 255, 255)) draw = ImageDraw.Draw(image_text) draw.text((0, 0), name, fill=(0, 0, 0), font=font) draw.text((0, 40), msg, fill=(125, 125, 125), font=font2) image_back = Image.new('RGB', (700, 150), (255, 255, 255)) image_back.paste(img_origin, (25, 25)) image_back.paste(image_text, (150, 40)) await bot.send(ev, str(MessageSegment.image(pic2b64(image_back))))
async def do_revgif(bot, ev, image_url, ifturn): print("正在准备图片") response = await aiorequests.get(image_url, headers=headers) image = Image.open(BytesIO(await response.content)) info = image.info print(f"frames:{image.n_frames}, mode:{image.mode}, info:{image.info}") if image.n_frames == 1: await bot.finish(ev, "并非GIF图片") if image.n_frames > 200: await bot.finish(ev, "GIF帧数太多了,懒得倒放[CQ:face,id=13]") turnAround = random.randint(0, 6) sequence = [f.transpose(turnAround).copy() if ifturn else f.copy() for f in ImageSequence.Iterator(image)] if len(sequence) > 30: await bot.send(ev, "ℹ正在翻转图片序列,请稍候") sequence.reverse() buf = BytesIO() sequence[0].save(buf, format='GIF', save_all=True, append_images=sequence[1:], disposal=2, quality=80, **info) base64_str = base64.b64encode(buf.getvalue()).decode() await bot.send(ev, ms.image('base64://' + base64_str))
def get_random_cards(card_file_names_list=card_file_names_all, amount=1): card_ids = [] size = 80 margin = 5 col_num = math.ceil(amount / 2) row_num = 2 if amount != 1 else 1 base = Image.new('RGBA', (col_num * size + (col_num - 1) * margin, (row_num * size + (row_num - 1) * margin)), (255, 255, 255, 255)) rarity_counter = {-1: 0, 0: 0, 1: 0} for i in range(amount): random_card = random.choice( card_file_names_list ) if card_file_names_list != card_file_names_all else random.choice( get_random_cards_list()) card_id, rarity = get_card_id_by_file_name(random_card) card_ids.append(card_id) rarity_counter[rarity] += 1 if PRELOAD: img = image_cache[random_card] else: img = Image.open(DIR_PATH + f'/{random_card}') row_index = i // col_num col_index = i % col_num img = img.resize((size, size), Image.ANTIALIAS) base.paste(add_rarity_frame(img, rarity), (col_index * (size + margin), row_index * (size + margin))) return card_ids, rarity_counter, MessageSegment.image(util.pic2b64(base))
async def add_repass(self, tag: str, data): po = "——{}——".format(tag) for line in data: if THUMB_ON: try: #thumbnail_image = str(MessageSegment.image(pic2b64(ats_pic(Image.open(BytesIO(await get_pic(line[2]))))))) thumbnail_image = str( MessageSegment.image( pic2b64( ats_pic( Image.open( BytesIO( self.scraper.get( line[2], timeout=20, proxies=proxies).content)))))) except Exception as e: print(format_exc()) thumbnail_image = "[预览图下载失败]" else: thumbnail_image = "" putline = f"{thumbnail_image}\n[{line[1]}][{line[0]}]\n{line[3]}" po = "\n".join([po, putline]) return po
async def on_input_image(bot, ev: CQEvent): if str(ev.group_id) not in gacha_threshold.threshold: return for seg in ev.message: if seg.type == 'image': img = seg.data['file'] need_ocr = await is_possible_gacha_image(bot, ev, img) if need_ocr: need_delete_msg, need_silence = await check_image(bot, ev, img) if need_delete_msg: bot_auth = judge_bot_auth(bot, ev) if need_silence: await bot.send(ev, '检测到海豹行为(╯‵□′)╯︵┻━┻') if bot_auth == True: await bot.delete_msg(self_id=ev.self_id, message_id=ev.message_id) await util.silence(ev, 10 * 60, skip_su=True) await bot.send( ev, str( MessageSegment.image( f'file:///{os.path.abspath(PIC_PATH)}')) + '\n拒绝海豹,从我做起!') else: if bot_auth == True: await bot.delete_msg(self_id=ev.self_id, message_id=ev.message_id) await bot.send(ev, '虽然没看出你有没有在晒卡,总之消息先撤回了~')
def get_icons(arr,size=64,types='skill'): num = len(arr) des = Image.new('RGBA', (num*size, size), (255, 255, 255, 255)) for i, chara in enumerate(arr): pic = icon(chara,types).open().convert('RGBA').resize((size, size), Image.LANCZOS) des.paste(pic, (i * size, 0), pic) return str(MessageSegment.image(pic2b64(des)))
async def jc(bot, ev: CQEvent): kw = ev.message.extract_plain_text().strip() arr = kw.split('/') image = Image.open(os.path.join(os.path.dirname(__file__),'jichou.jpg')) # 创建Font对象: font = ImageFont.truetype(os.path.join(os.path.dirname(__file__),'simhei.ttf'), 80) time = datetime.datetime.now().strftime('%Y年%m月%d日') msg = f'{time},{arr[0]},{arr[1]},这个仇我先记下了' place = 12 line = len(msg.encode('utf-8')) // place + 1 positions = measure(msg, 80, 974) str_list = list(msg) for pos in positions: str_list.insert(pos,'\n') msg = "".join(str_list) # 创建Draw对象: image_text = Image.new('RGB', (974, 32 * line), (255, 255, 255)) draw = ImageDraw.Draw(image_text) draw.text((0, 0), msg, fill=(0 , 0, 0), font=font) # 模糊: image_text = image_text.filter(ImageFilter.BLUR) image_back = Image.new('RGB', (974, 32 * line + 764), (255, 255, 255)) image_back.paste(image, (0, 0)) image_back.paste(image_text, (0, 764)) await bot.send(ev, str(MessageSegment.image(pic2b64(image_back))))
async def diary(bot, ev: CQEvent): global pre name = '富婆' for i in ev.message: if i.get('type', False) == 'at': name = get_name(i.data['qq']) kw = ev.message.extract_plain_text().strip() time = datetime.datetime.now().strftime('%Y年%m月%d日') arr = kw.split('/') content = '' if len(arr) >= 2: weather, content = arr weather = weather.split(' ')[-1] else: weather = '' if arr[0].split(' ') == 2: weather = arr[0].split(' ')[-1] if not content: with open(os.path.join(os.path.dirname(__file__), 'diary_data.json'), 'r', encoding='utf-8') as file: diaries = json.load(file) while True: index = random.randint(0, len(diaries) - 1) if index != pre: pre = index content = diaries[index] for s in '你她': content = content.replace(s, name) break image = Image.open(os.path.join(os.path.dirname(__file__), 'diary.png')) img_width, img_height = image.size # 创建Font对象: font_size = img_width // 18 font = ImageFont.truetype( os.path.join(os.path.dirname(__file__), 'simhei.ttf'), font_size) positions = measure(content, font_size, img_width) str_list = list(content) for pos in positions: str_list.insert(pos, '\n') # 日期单独一行 line = len(positions) + 2 content = f'{time},{weather}\n' + "".join(str_list) line_h = font_size + 4 # 创建Draw对象: image_text = Image.new('RGB', (img_width, line_h * line), (255, 255, 255)) draw = ImageDraw.Draw(image_text) draw.text((0, 0), content, fill=(0, 0, 0), font=font, spacing=2) # 模糊: # image_text = image_text.filter(ImageFilter.BLUR) image_back = Image.new('RGB', (img_width, line_h * line + img_height), (255, 255, 255)) image_back.paste(image, (0, 0)) image_back.paste(image_text, (0, img_height)) await bot.send(ev, str(MessageSegment.image(pic2b64(image_back))))
async def get_song_info_from_song(song): song_data = _song_data.SONG_DATA[song] pic_url = await get_pic_url(song_data[5]) if song_data[5] else "" img = MessageSegment.image(pic_url) if pic_url else "" msg_part = '' if song_data[6] == '' else '\n-------------------------------------------\n' song_info = song_data[2] + song + str(img) + '歌曲名: ' + song_data[3] + '\n' + '歌手: ' + song_data[4] + msg_part + \ song_data[6] return song_info, song_data
def format_tweet(tweet): name = tweet.user.name time = format_time(tweet.created_at) text = tweet.text media = tweet.get('extended_entities', {}).get('media', []) imgs = ' '.join([str(ms.image(m.media_url)) for m in media]) msg = f"@{name}\n{time}\n\n{text}" if imgs: msg = f"{msg}\n{imgs}" return msg
async def avatar_find(bot, ev: CQEvent): if gm.is_playing(ev.group_id): await bot.finish(ev, "游戏仍在进行中…") with gm.start_game(ev.group_id) as game: game.answer, answer_pic = get_merge_avatar() answer_pic = MessageSegment.image(util.pic2b64(answer_pic)) await bot.send(ev, f'请找出不一样的头像坐标?({ONE_TURN_TIME}s后公布答案){answer_pic}') await asyncio.sleep(ONE_TURN_TIME) if game.winner: return await bot.send(ev, f'正确答案是: {game.answer}\n很遗憾,没有人答对~')
async def perfect_match(bot, ev: CQEvent): if gm.is_playing(ev.group_id): await bot.finish(ev, "游戏仍在进行中…") with gm.start_game(ev.group_id) as game: chosen_ids = random.sample(game_util.VALID_IDS, TOTAL_PIC_NUM) pushed_index = set() # 发送若干轮的隐藏部分子图的合成图,保证所有子图至少都被发送一次。发送完毕后等待若干秒再撤回图片 for i in range(TURN_NUM): await bot.send(ev, f'记忆阶段{i+1}/{TURN_NUM}: ({BASIC_SHOW_TIME - i * 2}s后我会撤回图片哦~)') if i < TURN_NUM-1: shown_index = random.sample(range(TOTAL_PIC_NUM), TOTAL_PIC_NUM - HIDDEN_NUM) ids = [chosen_ids[i] if i in shown_index else game_util.UNKNOWN_ID for i in range(TOTAL_PIC_NUM)] pushed_index = pushed_index.union(set(shown_index)) else: remnant_index = set(range(TOTAL_PIC_NUM)) - pushed_index shown_index = list(remnant_index) shown_index.extend(random.sample(pushed_index, TOTAL_PIC_NUM - HIDDEN_NUM - len(remnant_index))) ids = [chosen_ids[i] if i in shown_index else game_util.UNKNOWN_ID for i in range(TOTAL_PIC_NUM)] pic = MessageSegment.image(util.pic2b64(game_util.generate_full_pic(ROW_NUM, COL_NUM, ids))) msg = await bot.send(ev, pic) await asyncio.sleep(BASIC_SHOW_TIME - i * 2) await bot.delete_msg(message_id=msg['message_id']) await asyncio.sleep(3) # 开始答题 correct_index = random.randint(0, TOTAL_PIC_NUM - 1) correct_id = chosen_ids[correct_index] game.answer = correct_index + 1 correct_pic_img = MessageSegment.image(util.pic2b64(game_util.get_sub_pic_from_id(correct_id))) answer_number_img = MessageSegment.image(f'file:///{os.path.abspath(game_util.BACKGROUND_PIC_PATH)}') await bot.send(ev, f'还记得"{game_util.EXPLANATION[correct_id]}"的位置吗?{correct_pic_img}请告诉我它的编号~ ({ANSWER_TIME}s后公布答案){answer_number_img}') await asyncio.sleep(ANSWER_TIME) # 结算 game.update_score() msg_part1 = f'{MessageSegment.at(game.winner[0])}首先答对,真厉害~ 加2分! 当前总分为{game.get_first_winner_score()}分' if game.winner else '' msg_part2 = f'{game_util.generate_at_message_segment(game.winner[1:])}也答对了, 加1分~' if game.winner[1:] else '' msg_part3 = f'{game_util.generate_at_message_segment(game.loser)}答错了, 扣1分o(╥﹏╥)o' if game.loser else '' msg_part4 = '咦, 这轮游戏没人参与, 看来题目可能有点难...' if not (msg_part1 or msg_part2 or msg_part3) else "" msg_part = '\n'.join([s for s in [msg_part1, msg_part2, msg_part3, msg_part4] if s]) await bot.send(ev, f'正确答案是: {game.answer}{MessageSegment.image(util.pic2b64(game_util.generate_full_pic(ROW_NUM, COL_NUM, chosen_ids)))}{msg_part}')
async def see_a_see_frame(bot, ev): user_id = str(ev.user_id) current_dir = os.path.join(os.path.dirname(__file__), 'frame.json') with open(current_dir, 'r', encoding='UTF-8') as f: f_data = json.load(f) id_list = list(f_data['customize'].keys()) if user_id not in id_list: frame_tmp = f_data['default_frame'] else: frame_tmp = f_data['customize'][user_id] path = os.path.join(os.path.dirname(__file__), f'img/frame/{frame_tmp}') msg = MessageSegment.image(f'file:///{os.path.abspath(path)}') await bot.send(ev, msg)
async def show_custom_reply(bot, ev): if not ev.group_id: await bot.finish(ev, "抱歉,自定义回复仅可在群聊中使用") msg = "[本群自定义回复]\n" if custom_reply.get(str(ev.group_id)): for key in custom_reply.get(str(ev.group_id)): msg += f"{html.unescape(key)}: {custom_reply.get(str(ev.group_id))[key]['content']}\n" else: msg += "无\n" msg += "[全局自定义回复]\n" for key in custom_reply.get("global"): msg += f"{html.unescape(key)}: {custom_reply.get('global')[key]['content']}\n" await bot.send(ev, MessageSegment.image(text2img(msg)))
async def spider_work(spider: BaseSpider, bot, gid, sv: Service, TAG): if not spider.item_cache[gid]: await spider.get_update(gid) sv.logger.info(f'群{gid}的{TAG}缓存为空,已加载至最新') return updates = await spider.get_update(gid) if not updates: sv.logger.info(f'群{gid}的{TAG}未检索到新视频') return sv.logger.info(f'群{gid}的{TAG}检索到{len(updates)}个新视频!') msg_list = spider.format_items(updates) for i in range(len(updates)): pic = MessageSegment.image('http:' + updates[i].pic) msg = f'{msg_list[0]}{pic}{msg_list[i+1]}' await bot.send_group_msg(group_id=int(gid), message=msg)
async def get_view(self, sauce) -> str: sauces = await self.get_sauce(sauce) repass = "" simimax = 0 for sauce in sauces['results']: try: url = sauce['data']['ext_urls'][0].replace( "\\", "").strip() if 'ext_urls' in sauce['data'] else "no link" similarity = sauce['header']['similarity'] if not similarity.replace(".", "").isdigit(): #print(sauce) similarity = 0 simimax = float( similarity) if float(similarity) > simimax else simimax thumbnail_url = sauce['header']['thumbnail'] if THUMB_ON: try: thumbnail_image = str( MessageSegment.image( pic2b64( ats_pic( Image.open( BytesIO( await get_pic(thumbnail_url))))))) except Exception as e: print(format_exc()) thumbnail_image = "[预览图下载失败]" else: thumbnail_image = "" service_name, info = sauces_info(sauce) putline = f"{thumbnail_image}\n[{service_name}][{url}] 相似度:{similarity}%\n{info}" if repass: repass = "******".join([repass, putline]) else: repass = putline except Exception as e: print(format_exc()) #print(sauce) pass return [repass, simimax]
def format_tweet(tweet): name = tweet.user.name if peony.events.retweet(tweet): return f"@{name} 转推了\n>>>>>\n{format_tweet(tweet.retweeted_status)}" time = format_time(tweet.created_at) text = tweet.text media = tweet.get("extended_entities", {}).get("media", []) imgs = " ".join([str(ms.image(m.media_url)) for m in media]) msg = f"@{name}\n{time}\n\n{text}" if imgs: msg = f"{msg}\n{imgs}" if "quoted_status" in tweet: quoted_msg = format_tweet(tweet.quoted_status) msg = f"{msg}\n\n>>>>>\n{quoted_msg}" return msg
async def migang_reply_help(bot, ev): msg = """ [添加群自定义回复] [基础] .migangreply add 关键词 自定义回复 [进阶] .migangreply add 关键词 自定义回复 0 (在回复时不at对方, 最后参数默认为0) .migangreply add 关键词 自定义回复 1 (在回复时at对方) [删除群自定义回复] .migangreply del 关键词 [查看自定义回复] 米缸查看自定义回复 [Tips] 图片请不要直接使用粘贴方式设定自定义回复,否则未来会失效,建议采用图床上传图片 类似([CQ:image,file=https://image.cinte.cc/2021/01/24/886d904a65e51.png]) (群自定义回复优先级高于维护者设定的全局自定义回复, 仅在群聊中可使用自定义回复) """.strip() await bot.send(ev, MessageSegment.image(text2img(msg)))
async def on_input_image(bot, ev: CQEvent): if str(ev.group_id) not in gacha_threshold.threshold: return for seg in ev.message: if seg.type == 'image': img = seg.data['file'] need_ocr = await is_possible_gacha_image(bot, ev, img) if need_ocr: need_delete_msg, need_silence = await check_image(bot, ev, img) if need_delete_msg: #if need_silence: await bot.send(ev, '检测到海豹行为(╯‵□′)╯︵┻━┻') # await bot.delete_msg(self_id=ev.self_id, message_id=ev.message_id) # await util.silence(ev, 10*60, skip_su=False) await bot.send( ev, botname + '提醒您:\n' + str( MessageSegment.image( f'file:///{os.path.abspath(PIC_PATH)}')) + '\n拒绝海豹,从我做起')
async def avatar_guess(bot, ev: CQEvent): if gm.is_playing(ev.group_id): await bot.finish(ev, "游戏仍在进行中…") with gm.start_game(ev.group_id) as game: ids = list(_pcr_data.CHARA_NAME.keys()) game.answer = random.choice(ids), random.choice((3, 6)) while chara.is_npc(game.answer[0]): game.answer = random.choice(ids), random.choice((3, 6)) c = chara.fromid(game.answer[0], game.answer[1]) img = c.icon.open() w, h = img.size l = random.randint(0, w - PATCH_SIZE) u = random.randint(0, h - PATCH_SIZE) cropped = img.crop((l, u, l + PATCH_SIZE, u + PATCH_SIZE)) cropped = Seg.image(util.pic2b64(cropped)) await bot.send(ev, f"猜猜这个图片是哪位角色头像的一部分?({ONE_TURN_TIME}s后公布答案) {cropped}") await asyncio.sleep(ONE_TURN_TIME) if game.winner: return await bot.send(ev, f"正确答案是:{c.name} {c.icon.cqcode}\n很遗憾,没有人答对~")
async def change_frame(bot, ev): user_id = ev.user_id frame_tmp = ev.message.extract_plain_text() path = os.path.join(os.path.dirname(__file__), 'img/frame/') frame_list = os.listdir(path) if not frame_list: await bot.finish(ev, 'img/frame/路径下没有任何头像框,请联系维护组检查目录') if frame_tmp not in frame_list: msg = f'文件名输入错误,命令样例:\n更换头像框 color.png\n目前可选文件有:\n' + '\n'.join(frame_list) await bot.finish(ev, msg) data = {str(user_id): frame_tmp} current_dir = os.path.join(os.path.dirname(__file__), 'frame.json') with open(current_dir, 'r', encoding='UTF-8') as f: f_data = json.load(f) f_data['customize'] = data with open(current_dir, 'w', encoding='UTF-8') as rf: json.dump(f_data, rf, indent=4, ensure_ascii=False) await bot.send(ev, f'已成功选择头像框:{frame_tmp}') frame_path = os.path.join(os.path.dirname(__file__), f'img/frame/{frame_tmp}') msg = MessageSegment.image(f'file:///{os.path.abspath(frame_path)}') await bot.send(ev, msg)
async def tank(bot, ev:CQEvent, type): url = extract_url_from_event(ev) if not url: await bot.finish(ev, '请附带图片!') if len(url) != 2: await bot.finish(ev, '图片数量不符!') print(url) await bot.send(ev, '请稍等片刻~') imgs = [] try: for i in range(len(url)): async with aiohttp.ClientSession() as session: async with session.get(url[i]) as resp: cont = await resp.read() imgs.append(Image.open(BytesIO(cont))) img_tank = await make_tank(imgs[0], imgs[1]) if type == 1 else await colorful_tank(imgs[0], imgs[1]) img_msg = MessageSegment.image('base64://' + base64.b64encode(img_tank).decode()) await bot.send(ev, img_msg) except: await bot.send(ev, '生成失败……')
async def get_next_song(gid): with Config(gid, CONFIG_PATH) as config: pushed_music = config.load_pushed_music() song_dict = _song_data.SONG_DATA songs = list(song_dict.keys()) random.shuffle(songs) all_pushed = True for song in songs: if song not in pushed_music: all_pushed = False break if all_pushed: song = songs[0] pushed_music = [] song_data = song_dict[song] pic_url = await get_pic_url(song_data[5]) if song_data[5] else "" img = MessageSegment.image(pic_url) if pic_url else "" msg_part = '' if song_data[ 6] == '' else '\n-------------------------------------------\n' song_info = song_data[2] + song + str(img) + '歌曲名: ' + song_data[ 3] + '\n' + '歌手: ' + song_data[4] + msg_part + song_data[6] pushed_music.append(song) config.save_pushed_music(pushed_music) return song_info, song_data
async def gen_5000_pic(bot, ev: CQEvent): uid = ev.user_id gid = ev.group_id mid = ev.message_id if not lmt.check(uid): await bot.send(ev, f'您今天已经使用过10次生成器了,休息一下明天再来吧~', at_sender=True) return try: keyword = ev.message.extract_plain_text().strip() if not keyword: await bot.send(ev, '请提供要生成的句子!') return if '|' in keyword: keyword = keyword.replace('|', '|') upper = keyword.split("|")[0] downer = keyword.split("|")[1] img = genImage(word_a=upper, word_b=downer) img = str(MessageSegment.image(pic2b64(img))) await bot.send(ev, img) lmt.increase(uid) except OSError: await bot.send(ev, '生成失败……请检查字体文件设置是否正确') except: await bot.send(ev, '生成失败……请检查命令格式是否正确')
def get_random_cards(origin_cards, card_file_names_list=card_file_names_all, amount=1, bonus=True): card_ids = [] size = 80 margin = 7 margin_offset_x = 6 margin_offset_y = 6 col_num = math.ceil(amount / 2) row_num = 2 if amount != 1 else 1 cards_amount = [] extra_bonus = False for i in range(amount): a = roll_extra_bonus() if bonus else 1 cards_amount.append(a) if a != 1: extra_bonus = True offset_y = 18 if extra_bonus else 0 offset_critical_strike = 7 if extra_bonus else 0 size_x, size_y = (col_num * size + (col_num + 1) * margin + 2 * margin_offset_x, offset_y + row_num * size + (row_num + 1) * margin + 2 * margin_offset_y + offset_critical_strike) base = Image.new('RGBA', (size_x, size_y), (255, 255, 255, 255)) frame = Image.open(FRAME_DIR_PATH + '/background.png') frame = frame.resize((size_x, size_y - offset_y), Image.ANTIALIAS) base.paste(frame, (0, offset_y), mask=frame.split()[3]) if extra_bonus: base = add_icon(base, 'pokecriticalstrike.png', int(size_x / 2) - 71, int(offset_y / 2) - 2) card_counter = {} card_descs = [] rarity_desc = {1: '超稀有', 0: '稀有', -1: '普通'} for i in range(amount): random_card = random.choice( card_file_names_list ) if card_file_names_list != card_file_names_all else random.choice( get_random_cards_list()) card_id, rarity = get_card_id_by_file_name(random_card) card_amount = cards_amount[i] card_counter[card_id] = card_amount new_string = ' 【NEW】' if card_id not in origin_cards else '' card_desc = f'{rarity_desc[rarity]}「{get_chara_name(card_id)[1]}」×{card_amount}{new_string}' card_descs.append(card_desc) if PRELOAD: img = image_cache[random_card] else: img = Image.open(DIR_PATH + f'/{random_card}') row_index = i // col_num col_index = i % col_num img = img.resize((size, size), Image.ANTIALIAS) img = add_rarity_frame(img, rarity) if card_amount > 1: img = add_card_amount(img, card_amount) coor_x, coor_y = (margin + margin_offset_x + col_index * (size + margin), margin + margin_offset_y + offset_y + offset_critical_strike + row_index * (size + margin)) base.paste(img, (coor_x, coor_y), mask=img.split()[3]) if card_id not in origin_cards: base = add_icon(base, 'new.png', coor_x + size - 27, coor_y - 5) return card_counter, card_descs, MessageSegment.image(util.pic2b64(base))
async def picfinder(bot, ev: CQEvent): ret = re.match(r"\[CQ:image,file=(.*),url=(.*)\]", str(ev.message)) image = Image.open(BytesIO(get_pic(ret.group(2)))) image = image.convert('RGB') image.thumbnail(thumbSize, resample=Image.ANTIALIAS) imageData = io.BytesIO() image.save(imageData,format='PNG') url = 'http://saucenao.com/search.php?output_type=2&numres=1&minsim='+minsim+'&dbmask='+str(db_bitmask)+'&api_key='+api_key files = {'file': ("image.png", imageData.getvalue())} imageData.close() await bot.send(ev, '正在搜索, 请稍等', at_sender=True) processResults = True counter = 0 while counter <= MAX_NUM: counter = counter+1 r = requests.post(url, files=files) if r.status_code != 200: if r.status_code == 403: await bot.send(ev, 'Key错误, 请联系维护者') return elif r.status_code == 429: await bot.send(ev, '请求次数过f多, 请联系维护者') return else: print("status code: "+str(r.status_code)) else: results = json.JSONDecoder(object_pairs_hook=OrderedDict).decode(r.text) if int(results['header']['user_id'])>0: print('搜索限制 30s|24h: '+str(results['header']['short_remaining'])+'|'+str(results['header']['long_remaining'])) if int(results['header']['status'])==0: #搜索所有索引成功,结果可用 break else: if int(results['header']['status'])>0: #一个或多个索引出现问题。 #即使所有索引都失败,此搜索仍被视为部分成功,因此仍将计入接口限制。 #错误可能是暂时的,请过段时间再重试。 print('API错误。请在600秒后重试。。。') else: #提交的搜索有问题,或请求出错。 #出现此问题请不要大量发送请求。 print('错误的图像或其他请求错误。。。') processResults = False break else: #api没有响应 #出现此问题请不要大量发送请求。 print('错误的图像或其他请求错误。。。') processResults = False break if processResults: if int(results['header']['results_returned']) > 0: #返回了一个或多个结果,判断相似度是否符合要求,取第一条结果 if float(results['results'][0]['header']['similarity']) > float(results['header']['minimum_similarity']): hit = str(results['results'][0]['header']['similarity']) ext_urls = results['results'][0]['data']['ext_urls'][0] thumbnail_url = results['results'][0]['header']['thumbnail'] thumbnail_image = str(MessageSegment.image(pic2b64(Image.open(BytesIO(get_pic(thumbnail_url)))))) service_name = '' illust_id = 0 member_id = -1 author_name = '' title = '' index_id = results['results'][0]['header']['index_id'] page_string = '' page_match = re.search(r'(_p[\d]+)\.', results['results'][0]['header']['thumbnail']) if page_match: page_string = page_match.group(1) if index_id == 5 or index_id == 6: #5->pixiv 6->pixiv historical service_name='pixiv' member_id = results['results'][0]['data']['member_id'] illust_id=results['results'][0]['data']['pixiv_id'] author_name = results['results'][0]['data']['member_name'] title = results['results'][0]['data']['title'] elif index_id == 8: service_name='nico nico seiga' member_id = results['results'][0]['data']['member_id'] illust_id=results['results'][0]['data']['seiga_id'] author_name = results['results'][0]['data']['member_name'] title = results['results'][0]['data']['title'] # elif index_id == 9:#启用此项需自行修改获取返回的结构 # service_name='Danbooru' # member_id = results['results'][0]['data']['member_id'] # illust_id=results['results'][0]['data']['drawr_id'] elif index_id == 10: service_name='drawr Images' member_id = results['results'][0]['data']['member_id'] illust_id=results['results'][0]['data']['drawr_id'] elif index_id == 11: service_name='Nijie Images' member_id = results['results'][0]['data']['member_id'] illust_id=results['results'][0]['data']['nijie_id'] # elif index_id == 12:#启用此项需自行修改获取返回的结构 # service_name='Yande.re' # member_id = results['results'][0]['data']['member_id'] # illust_id=results['results'][0]['data']['yande_id'] # elif index_id == 18 or index_id == 38:#启用此项需自行修改获取返回的结构 # service_name='H-Misc' # member_id = results['results'][0]['data']['member_id'] # illust_id=results['results'][0]['data']['nijie_id'] # elif index_id == 19:#启用此项需自行修改获取返回的结构 # service_name='2D-Market' # member_id = results['results'][0]['data']['member_id'] # illust_id=results['results'][0]['data']['nijie_id'] elif index_id == 21: service_name='Anime' title = results['results'][0]['data']['source'] illust_id=results['results'][0]['data']['anidb_aid'] # elif index_id == 22:#启用此项需自行修改获取返回的结构 # service_name='H-Anime' # member_id = results['results'][0]['data']['member_id'] # illust_id=results['results'][0]['data']['nijie_id'] # elif index_id == 25:#启用此项需自行修改获取返回的结构 # service_name='Gelbooru' # member_id = results['results'][0]['data']['member_id'] # illust_id=results['results'][0]['data']['nijie_id'] # elif index_id == 26:#启用此项需自行修改获取返回的结构 # service_name='Konachan' # member_id = results['results'][0]['data']['member_id'] # illust_id=results['results'][0]['data']['nijie_id'] # elif index_id == 27: # service_name='Sankaku Channel' # illust_id=results['results'][0]['data']['sankaku_id'] # author_name = results['results'][0]['data']['creator'] # title = results['results'][0]['data']['material'] # elif index_id == 28:#启用此项需自行修改获取返回的结构 # service_name='Anime-Pictures.net' # member_id = results['results'][0]['data']['member_id'] # illust_id=results['results'][0]['data']['nijie_id'] # elif index_id == 29:#启用此项需自行修改获取返回的结构 # service_name='e621.net' # member_id = results['results'][0]['data']['member_id'] # illust_id=results['results'][0]['data']['nijie_id'] # elif index_id == 30:#启用此项需自行修改获取返回的结构 # service_name='Idol Complex' # member_id = results['results'][0]['data']['member_id'] # illust_id=results['results'][0]['data']['nijie_id'] # elif index_id == 31: # service_name='bcy.net Illust' # member_id = results['results'][0]['data']['member_id'] # illust_id=results['results'][0]['data']['bcy_id'] # author_name = results['results'][0]['data']['member_name'] # title = results['results'][0]['data']['title'] # elif index_id == 33:#启用此项需自行修改获取返回的结构 # service_name='PortalGraphics.net' # member_id = results['results'][0]['data']['member_id'] # illust_id=results['results'][0]['data']['nijie_id'] elif index_id == 34: service_name='deviantArt' illust_id=results['results'][0]['data']['da_id'] author_name = results['results'][0]['data']['pawoo_user_username'] title = results['results'][0]['data']['title'] # elif index_id == 35: # service_name='Pawoo.net' # illust_id=results['results'][0]['data']['pawoo_id'] # author_name = results['results'][0]['data']['author_name'] # title = results['results'][0]['data']['pawoo_user_display_name'] # elif index_id == 36:#启用此项需自行修改获取返回的结构 # service_name='Madokami (Manga)' # member_id = results['results'][0]['data']['member_id'] # illust_id=results['results'][0]['data']['nijie_id'] # elif index_id == 37:#启用此项需自行修改获取返回的结构 # service_name='MangaDex' # member_id = results['results'][0]['data']['member_id'] # illust_id=results['results'][0]['data']['nijie_id'] else: #unknown print(f'未知的索引编号:{index_id}') await bot.send(ev, '没有查询到相似图片。。。') try: if member_id >= 0: if author_name: await bot.send(ev, thumbnail_image+'\n相似度:'+hit+'\n来源:'+service_name+'\n标题:'+title+'\n作者:'+author_name+'('+str(member_id)+')'+'\n编号:'+str(illust_id)+page_string+'\nurl:'+ext_urls) else: await bot.send(ev, thumbnail_image+'\n相似度:'+hit+'\n来源:'+service_name+'\n标题:'+title+'\n编号:'+str(illust_id)+page_string+'\nurl:'+ext_urls) else: if author_name: await bot.send(ev, thumbnail_image+'\n相似度:'+hit+'\n来源:'+service_name+'\n标题:'+title+'\n作者:'+author_name+'\n编号:'+str(illust_id)+page_string+'\nurl:'+ext_urls) else: await bot.send(ev, thumbnail_image+'\n相似度:'+hit+'\n来源:'+service_name+'\n标题:'+title+'\n编号:'+str(illust_id)+page_string+'\nurl:'+ext_urls) except Exception as e: print(e) else: await bot.send(ev, '相似度'+str(results['results'][0]['header']['similarity'])+'过低,可能:确实找不到此图/图为原图的局部图/图清晰度太低/搜索引擎尚未同步新图') else: await bot.send(ev, '没有查询到相似图片。。。') if int(results['header']['long_remaining'])<1: print('超过今日的搜索上限,请在6小时后重试。。。') if int(results['header']['short_remaining'])<1: print('超过30s的搜索上限,请在25s后重试。。。')
def get_random_cards(origin_cards, row_num, col_num, amount, bonus, get_random_cards_func=get_random_cards_list, *args): size = 80 margin = 7 margin_offset_x = 6 margin_offset_y = 6 cards_amount = [] extra_bonus = False for i in range(amount): a = roll_extra_bonus() if bonus else 1 cards_amount.append(a) if a != 1: extra_bonus = True offset_y = 18 if extra_bonus else 0 offset_critical_strike = 7 if extra_bonus else 0 size_x, size_y = (col_num * size + (col_num + 1) * margin + 2 * margin_offset_x, offset_y + row_num * size + (row_num + 1) * margin + 2 * margin_offset_y + offset_critical_strike) base = Image.new('RGBA', (size_x, size_y), (255, 255, 255, 255)) frame = Image.open(FRAME_DIR_PATH + '/background.png') frame = frame.resize((size_x, size_y - offset_y), Image.ANTIALIAS) base.paste(frame, (0, offset_y), mask=frame.split()[3]) if extra_bonus: base = add_icon(base, 'pokecriticalstrike.png', int(size_x / 2) - 71, int(offset_y / 2) - 2) card_counter = {} rarity_counter = {1: [0, 0], 0: [0, 0], -1: [0, 0]} card_descs = [] rarity_desc = {1: '超稀有', 0: '稀有', -1: '普通'} for i in range(amount): random_card = random.choice(get_random_cards_func(*args)) card_id, rarity = get_card_id_by_file_name(random_card) new_string = ' 【NEW】' if card_id not in origin_cards and card_id not in card_counter else '' card_amount = cards_amount[i] card_counter[ card_id] = card_amount if card_id not in card_counter else card_counter[ card_id] + card_amount card_desc = f'{rarity_desc[rarity]}「{get_chara_name(card_id)[1]}」×{card_amount}{new_string}' card_descs.append(card_desc) rarity_counter[rarity][0] += 1 rarity_counter[rarity][1] += 1 if new_string else 0 if PRELOAD: img = image_cache[random_card] else: img = Image.open(DIR_PATH + f'/{random_card}') img = img.convert('RGBA') if img.mode != 'RGBA' else img row_index = i // col_num col_index = i % col_num img = img.resize((size, size), Image.ANTIALIAS) img = add_rarity_frame(img, rarity) if card_amount > 1: img = add_card_amount(img, card_amount) coor_x, coor_y = (margin + margin_offset_x + col_index * (size + margin), margin + margin_offset_y + offset_y + offset_critical_strike + row_index * (size + margin)) base.paste(img, (coor_x, coor_y), mask=img.split()[3]) if card_id not in origin_cards: base = add_icon(base, 'new.png', coor_x + size - 27, coor_y - 5) # 当获得的卡片数过多时,只显示各稀有度获得的卡片数量 if amount > OMIT_THRESHOLD: card_descs = [] rarity_desc = {1: '超稀有', 0: '稀有卡', -1: '普通卡'} for rarity in rarity_counter: if rarity_counter[rarity][0] > 0: msg_part = f' (【NEW】x{rarity_counter[rarity][1]})' if rarity_counter[ rarity][1] else '' card_descs.append( f'【{rarity_desc[rarity]}】x{rarity_counter[rarity][0]}{msg_part}' ) return card_counter, card_descs, MessageSegment.image(util.pic2b64(base))
async def traceanime(bot, ev: CQEvent): ret = re.match(r"\[CQ:image,file=(.*),url=(.*)\]", str(ev.message)) pic_url = ret.group(2) url = f'https://trace.moe/api/search?url={pic_url}' try: with requests.get(url, timeout=20) as resp: res = resp.json() data = res['docs'][0] print(data) similarity = "%.2f%%" % (data['similarity'] * 100) episode = data['episode'] time = datetime.timedelta(seconds=data['at']) anilist_id = data['anilist_id'] title_native = data['title_native'] title_chinese = data['title_chinese'] title_english = data['title_english'] limit = res['limit'] limit_ttl = res['limit_ttl'] is_adult = '分级:普通' # 此段注释为匹配到的视频片段地址,mute_video_url为静音浏览的地址 # filename = data['filename'] # at = data['at'] # token = data['tokenthumb'] # video_url = f'https://media.trace.moe/video/{anilist_id}/{filename}?t={at}&token={tokenthumb}`' # mute_video_url = f'https://media.trace.moe/video/{anilist_id}/{filename}?t={at}&token={tokenthumb}&mute`' if data['is_adult']: is_adult = '分级:限制级' if data['similarity'] < minsim: msg = '相似度' + similarity + '过低,可能原因:图片为局部图/图片清晰度太低。。。' else: details_str = '' if enable_details: details = get_details(anilist_id) #过滤里番封面 if data['is_adult']: image = '' else: image = str( MessageSegment.image( pic2b64( Image.open( BytesIO( get_pic(details['coverImage'] ['large'].replace( '\\', ''))))))) types = details['type'] formats = details['format'] ep_num = details['episodes'] start = str(details['startDate']['year']) + '-' + str( details['startDate']['month']) + '-' + str( details['startDate']['day']) if details['status'] == 'FINISHED': end = str(details['endDate']['year']) + '-' + str( details['endDate']['month']) + '-' + str( details['endDate']['day']) else: end = '未完结' details_str = f'{image}\n类型:{types}-{formats},共{ep_num}集\n开播:{start}\n完结:{end}\n' if type(episode) is int: msg = f'[{similarity}]该截图出自第{episode}集{time}\n{title_native}\n{title_chinese}\n{title_english}\n{details_str}{is_adult}' else: msg = f'[{similarity}]该截图出自{episode}{time}\n{title_native}\n{title_chinese}\n{title_english}\n{details_str}{is_adult}' await bot.send( ev, msg + '\n低于87%的结果可能会不太准确(可能原因:图片为局部图/图片清晰度太低)\n剩余查询次数:' + str(limit) + ',查询数+1剩余时间:' + str(limit_ttl) + 's') except Exception as ex: print(ex) await bot.send(ev, '查询错误,请稍后重试。。。')