import math import os import random import sqlite3 import time import traceback import urllib import numpy as np from typing import List from wordcloud import WordCloud from PIL import Image, ImageDraw, ImageFilter from pyrogram.types import Message from defs.db2 import MysSign, GetDaily, cacheDB, GetMysInfo, errorDB, GetInfo, GetSpiralAbyssInfo, GetAward from defs.event import ys_font from genshinstats.genshinstats.daily import DailyRewardInfo WEAPON_PATH = os.path.join("assets", 'weapon') BG_PATH = os.path.join("assets", "bg") CHAR_DONE_PATH = os.path.join("assets", 'char_done') BG2_PATH = os.path.join("assets", "bg2") CHAR_PATH = os.path.join("assets", "characters") CHAR_IMG_PATH = os.path.join("assets", 'char_img') REL_PATH = os.path.join("assets", "reliquaries") avatar_json = { "Albedo": "阿贝多", "Ambor": "安柏", "Barbara": "芭芭拉", "Beidou": "北斗", "Bennett": "班尼特", "Chongyun": "重云", "Diluc": "迪卢克", "Diona": "迪奥娜", "Eula": "优菈", "Fischl": "菲谢尔", "Ganyu": "甘雨", "Hutao": "胡桃", "Jean": "琴", "Kazuha": "枫原万叶", "Kaeya": "凯亚", "Ayaka": "神里绫华", "Keqing": "刻晴", "Klee": "可莉", "Lisa": "丽莎", "Mona": "莫娜", "Ningguang": "凝光", "Noel": "诺艾尔", "Qiqi": "七七", "Razor": "雷泽", "Rosaria": "罗莎莉亚", "Sucrose": "砂糖", "Tartaglia": "达达利亚", "Venti": "温迪", "Xiangling": "香菱", "Xiao": "魈", "Xingqiu": "行秋", "Xinyan": "辛焱", "Yanfei": "烟绯", "Zhongli": "钟离", "Yoimiya": "宵宫", "Sayu": "早柚", "Shogun": "雷电将军", "Aloy": "埃洛伊", "Sara": "九条裟罗", "Kokomi": "珊瑚宫心海", "Shenhe": "申鹤" } award_json = { "Mail": "邮件奖励", "Events": "活动奖励", "Adventure": "冒险奖励", "Daily Activity": "每日活跃", "Quests": "任务奖励", "Spiral Abyss": "深境螺旋", "Other": "其他", } daily_im = ''' *数据刷新可能存在一定延迟,请以当前游戏实际数据为准{} ============== 原粹树脂:{}/{}{} 每日委托:{}/{} 奖励{}领取 周本减半:{}/{} 洞天宝钱:{} 探索派遣: 总数/完成/上限:{}/{}/{} {}''' month_im = ''' ============== {} UID:{} ============== 本日获取原石:{} 本日获取摩拉:{} ============== 本月获取原石:{} 本月获取摩拉:{} ============== 上月获取原石:{} 上月获取摩拉:{} ============== 原石收入组成: {}==============''' def trans_award(string: str) -> str: if string in award_json: return award_json[string] else: return string async def award(uid): data = await GetAward(uid) if data is None: # 等级太低,或者不够活跃 return "暂无每月统计信息" nickname = data['nickname'] day_stone = data['day_data']['current_primogems'] day_mora = data['day_data']['current_mora'] month_stone = data['month_data']['current_primogems'] month_mora = data['month_data']['current_mora'] lastmonth_stone = data['month_data']['last_primogems'] lastmonth_mora = data['month_data']['last_mora'] group_str = '' for i in data['month_data']['group_by']: group_str = group_str + \ trans_award(i['action']) + ":" + str(i['num']) + \ "(" + str(i['percent']) + "%)" + '\n' im = month_im.format(nickname, uid, day_stone, day_mora, month_stone, month_mora, lastmonth_stone, lastmonth_mora, group_str) return im # 签到函数 async def sign(uid): try: sign_data = await MysSign(uid) if sign_data: if isinstance(sign_data, DailyRewardInfo): mes_im = "已经签到过了!" get_im = f"本月已经签到了 {sign_data.claimed_rewards} 天" else: mes_im = "签到成功" get_im = f"本次签到获得{sign_data['name']}x{sign_data['cnt']}" im = mes_im + "!" + "\n" + get_im else: im = "签到失败,请检查Cookies是否失效。" except: im = "签到失败,请检查Cookies是否失效。" return im # 统计状态函数 async def daily(mode="push", uid=None): def seconds2hours(seconds: int) -> str: m, s = divmod(int(seconds), 60) h, m = divmod(m, 60) return "%02d:%02d:%02d" % (h, m, s) temp_list = [] conn = sqlite3.connect('ID_DATA_OR.db') c = conn.cursor() if mode == "ask": c_data = ([uid, 0, 0, 0, 0, 0, 0],) else: cursor = c.execute( "SELECT * FROM NewCookiesTable WHERE StatusA != ?", ("off",)) c_data = cursor.fetchall() for row in c_data: try: dailydata = await GetDaily(str(row[0])) except Exception as e: if str(e).find("用户信息不匹配"): temp_list.append( {"qid": row[2], "gid": row[3], "message": "你的推送状态有误;可能是uid绑定错误或没有在米游社打开“实时便筏”功能。"}) else: traceback.print_exc() else: current_resin = dailydata['resin'] current_expedition_num = len(dailydata['expeditions']) max_expedition_num = dailydata['max_expeditions'] finished_expedition_num = 0 expedition_info: List[str] = [] for expedition in dailydata['expeditions']: avatar: str = expedition['icon'][92:-4] try: avatar_name: str = avatar_json[avatar] except KeyError: avatar_name: str = avatar if expedition['status'] == 'Finished': expedition_info.append(f"{avatar_name} 探索完成") finished_expedition_num += 1 else: remained_timed: str = seconds2hours( expedition['remaining_time']) expedition_info.append( f"{avatar_name} 剩余时间{remained_timed}") if current_resin >= row[6] or dailydata["max_realm_currency"] - dailydata[ "realm_currency"] <= 100 or finished_expedition_num > 0: tip = '' if current_resin >= row[6] != 0: tip += "\n==============\n你的树脂快满了!" if dailydata["max_realm_currency"] - dailydata["realm_currency"] <= 100: tip += "\n==============\n你的洞天宝钱快满了!" if finished_expedition_num > 0: tip += "\n==============\n你有探索派遣完成了!" max_resin = dailydata['max_resin'] rec_time = '' # print(dailydata) if current_resin < 160: resin_recovery_time = seconds2hours( dailydata['until_resin_limit']) next_resin_rec_time = seconds2hours( 8 * 60 - ((dailydata['max_resin'] - dailydata['resin']) * 8 * 60 - int( dailydata['until_resin_limit']))) rec_time = f' ({next_resin_rec_time}/{resin_recovery_time})' finished_task_num = dailydata['completed_commissions'] total_task_num = dailydata['total_commissions'] is_extra_got = '已' if dailydata['claimed_commission_reward'] else '未' resin_discount_num_limit = dailydata['max_boss_discounts'] used_resin_discount_num = resin_discount_num_limit - \ dailydata['remaining_boss_discounts'] coin = f'{dailydata["realm_currency"]}/{dailydata["max_realm_currency"]}' if dailydata["realm_currency"] < dailydata["max_realm_currency"]: coin_rec_time = seconds2hours(int(dailydata["until_realm_currency_limit"])) coin_add_speed = math.ceil((dailydata["max_realm_currency"] - dailydata["realm_currency"]) / ( int(dailydata["until_realm_currency_limit"]) / 60 / 60)) coin += f'({coin_rec_time} 约{coin_add_speed}/h)' expedition_data = "\n".join(expedition_info) send_mes = daily_im.format(tip, current_resin, max_resin, rec_time, finished_task_num, total_task_num, is_extra_got, used_resin_discount_num, resin_discount_num_limit, coin, current_expedition_num, finished_expedition_num, max_expedition_num, expedition_data) temp_list.append( {"qid": row[2], "gid": row[3], "message": send_mes}) return temp_list def create_rounded_rectangle_mask(rectangle, radius): solid_fill = (50, 50, 50, 255) i = Image.new("RGBA", rectangle.size, (0, 0, 0, 0)) corner = Image.new('RGBA', (radius, radius), (0, 0, 0, 0)) draw = ImageDraw.Draw(corner) draw.pieslice((0, 0, radius * 2, radius * 2), 180, 270, fill=solid_fill) mx, my = rectangle.size i.paste(corner, (0, 0), corner) i.paste(corner.rotate(90), (0, my - radius), corner.rotate(90)) i.paste(corner.rotate(180), (mx - radius, my - radius), corner.rotate(180)) i.paste(corner.rotate(270), (mx - radius, 0), corner.rotate(270)) draw = ImageDraw.Draw(i) draw.rectangle([(radius, 0), (mx - radius, my)], fill=solid_fill) draw.rectangle([(0, radius), (mx, my - radius)], fill=solid_fill) return i def get_weapon_pic(url): urllib.request.urlretrieve(url, os.path.join(WEAPON_PATH, url.split('/')[-1])) def get_char_pic(id, url): urllib.request.urlretrieve(f'{url}', os.path.join(CHAR_PATH, f'{id}.png')) def get_charimg_pic(url): urllib.request.urlretrieve(url, os.path.join(CHAR_IMG_PATH, url.split('/')[-1])) def get_rel_pic(url): urllib.request.urlretrieve(url, os.path.join(REL_PATH, url.split('/')[-1])) async def draw_pic(uid, message: Message, nickname="1", mode=2, role_level=None): # 获取Cookies,如果没有能使用的则return while 1: use_cookies = cacheDB(uid, mode - 1) if use_cookies == '': return "绑定记录不存在。" elif use_cookies == "没有可以使用的Cookies!": return "没有可以使用的Cookies!" if mode == 3: mys_data = await GetMysInfo(uid, use_cookies) uid = mys_data[0]['uid'] nickname = mys_data[0]['nickname'] role_level = mys_data[0]['level'] try: raw_data = await GetInfo(uid, use_cookies) except Exception as e: if str(e).find("Cannnot get data for more than 30 accounts per day.") != -1: # return ("当前cookies已达到30人上限!") errorDB(use_cookies, "limit30") elif str(e).find("Login cookies have not been provided") != -1: # return ("Cookie错误/过期,请重置Cookie") errorDB(use_cookies, "error") else: traceback.print_exc() return ( "Api报错\r\n" + "\r\n出现这种情况可能是UID输入错误 or 不存在" ) else: break # 获取背景图片 bg2_path = os.path.join(BG_PATH, random.choice([x for x in os.listdir(BG_PATH) if os.path.isfile(os.path.join(BG_PATH, x))])) if message.media: image_data = await message.download() edit_bg = Image.open(image_data) else: edit_bg = Image.open(bg2_path) # 获取背景主色 q = edit_bg.quantize(colors=3, method=2) bg_num_temp = 0 for i in range(0, 3): bg = tuple(q.getpalette()[i * 3:(i * 3) + 3]) bg_num = bg[0] + bg[1] + bg[2] if bg_num >= bg_num_temp: bg_num_temp = bg_num bg_color = (bg[0], bg[1], bg[2]) # 通过背景主色(bg_color)确定文字主色 r = 140 if max(*bg_color) > 255 - r: r *= -1 new_color = (math.floor(bg_color[0] + r if bg_color[0] + r <= 255 else 255), math.floor(bg_color[1] + r if bg_color[1] + r <= 255 else 255), math.floor(bg_color[2] + r if bg_color[2] + r <= 255 else 255)) # 确定texture2D路径 panle1_path = os.path.join(BG2_PATH, "panle_1.png") panle3_path = os.path.join(BG2_PATH, "panle_3.png") avatar_bg_path = os.path.join(BG2_PATH, "avatar_bg.png") avatar_fg_path = os.path.join(BG2_PATH, "avatar_fg.png") all_mask_path = os.path.join(BG2_PATH, "All_Mask.png") # 记录数据 char_datas = raw_data["characters"] # 确定角色占用行数 char_num = len(char_datas) char_hang = 1 + (char_num - 1) // 6 if char_num > 8 else char_num # 确定整体图片的长宽 based_w = 900 based_h = 890 + char_hang * 130 if char_num > 8 else 890 + char_hang * 110 based_scale = '%.3f' % (based_w / based_h) # 通过确定的长宽比,缩放背景图片 w, h = edit_bg.size scale_f = '%.3f' % (w / h) new_w = math.ceil(based_h * float(scale_f)) new_h = math.ceil(based_w / float(scale_f)) if scale_f > based_scale: bg_img2 = edit_bg.resize((new_w, based_h), Image.ANTIALIAS) else: bg_img2 = edit_bg.resize((based_w, new_h), Image.ANTIALIAS) bg_img = bg_img2.crop((0, 0, 900, based_h)) # 转换遮罩的颜色、大小匹配,并paste上去 all_mask = Image.open(all_mask_path).resize(bg_img.size, Image.ANTIALIAS) all_mask_img = Image.new("RGBA", (based_w, based_h), bg_color) bg_img.paste(all_mask_img, (0, 0), all_mask) # 操作图片 panle1 = Image.open(panle1_path) panle3 = Image.open(panle3_path) avatar_bg = Image.open(avatar_bg_path) avatar_fg = Image.open(avatar_fg_path) # 确定主体框架 avatar_bg_color = Image.new("RGBA", (316, 100), bg_color) panle1_color = Image.new("RGBA", (900, 800), new_color) bg_img.paste(panle1_color, (0, 0), panle1) bg_img.paste(panle3, (0, char_hang * 130 + 800) if char_num > 8 else (0, char_hang * 110 + 800), panle3) bg_img.paste(avatar_bg_color, (113, 98), avatar_bg) bg_img.paste(avatar_fg, (114, 95), avatar_fg) # 绘制基础信息文字 text_draw = ImageDraw.Draw(bg_img) if role_level: text_draw.text((140, 200), "冒险等级:" + f"{role_level}", new_color, ys_font(20)) text_draw.text((220, 123), f"{nickname}", new_color, ys_font(32)) text_draw.text((235, 163), 'UID ' + f"{uid}", new_color, ys_font(14)) # 活跃天数/成就数量/深渊信息 text_draw.text((640, 94.8), str(raw_data['stats']['active_days']), new_color, ys_font(26)) text_draw.text((640, 139.3), str(raw_data['stats']['achievements']), new_color, ys_font(26)) text_draw.text((640, 183.9), raw_data['stats']['spiral_abyss'], new_color, ys_font(26)) # 宝箱 text_draw.text((258, 375.4), str("未知"), new_color, ys_font(24)) text_draw.text((258, 425.4), str(raw_data['stats']['common_chests']), new_color, ys_font(24)) text_draw.text((258, 475.4), str(raw_data['stats']['exquisite_chests']), new_color, ys_font(24)) text_draw.text((258, 525.4), str(raw_data['stats']['precious_chests']), new_color, ys_font(24)) text_draw.text((258, 575.4), str(raw_data['stats']['luxurious_chests']), new_color, ys_font(24)) # 已获角色 text_draw.text((740, 547), str(raw_data['stats']['characters']), new_color, ys_font(24)) # 开启锚点和秘境数量 text_draw.text((258, 625.4), str(raw_data['stats']['unlocked_waypoints']), new_color, ys_font(24)) text_draw.text((258, 675.4), str(raw_data['stats']['unlocked_domains']), new_color, ys_font(24)) # 蒙德 text_draw.text((490, 370), str(raw_data['explorations'][4]['explored']) + '%', new_color, ys_font(22)) text_draw.text((490, 400), 'lv.' + str(raw_data['explorations'][4]['level']), new_color, ys_font(22)) text_draw.text((513, 430), str(raw_data['stats']['anemoculi']), new_color, ys_font(22)) # 璃月 text_draw.text((490, 490), str(raw_data['explorations'][3]['explored']) + '%', new_color, ys_font(22)) text_draw.text((490, 520), 'lv.' + str(raw_data['explorations'][3]['level']), new_color, ys_font(22)) text_draw.text((513, 550), str(raw_data['stats']['geoculi']), new_color, ys_font(22)) # 雪山 text_draw.text((745, 373.5), str(raw_data['explorations'][2]['explored']) + '%', new_color, ys_font(22)) text_draw.text((745, 407.1), 'lv.' + str(raw_data['explorations'][2]['level']), new_color, ys_font(22)) # 稻妻 text_draw.text((490, 608), str(raw_data['explorations'][1]['explored']) + '%', new_color, ys_font(22)) text_draw.text((490, 635), 'lv.' + str(raw_data['explorations'][1]['level']), new_color, ys_font(22)) text_draw.text((490, 662), 'lv.' + str(raw_data['explorations'][1]['offerings'][0]['level']), new_color, ys_font(22)) text_draw.text((513, 689), str(raw_data['stats']['electroculi']), new_color, ys_font(22)) # 渊下宫 text_draw.text((745, 480), str(raw_data['explorations'][0]['explored']) + '%', new_color, ys_font(22)) # 家园 if raw_data['teapot']: text_draw.text((693, 582.4), 'lv.' + str(raw_data['teapot']['level']), new_color, ys_font(22)) text_draw.text((693, 620.4), str(raw_data['teapot']['visitors']), new_color, ys_font(22)) text_draw.text((693, 658.4), str(raw_data['teapot']['items']), new_color, ys_font(22)) text_draw.text((693, 696.4), str(raw_data['teapot']['comfort']), new_color, ys_font(22)) else: text_draw.text((693, 582.4), "未开", new_color, ys_font(22)) text_draw.text((693, 620.4), "未开", new_color, ys_font(22)) text_draw.text((693, 658.4), "未开", new_color, ys_font(22)) text_draw.text((693, 696.4), "未开", new_color, ys_font(22)) # 确定texture2D路径 charpic_mask_path = os.path.join(BG2_PATH, "charpic_mask.png") weaponpic_mask_path = os.path.join(BG2_PATH, "weaponpic_mask.png") def getText(star, step): return os.path.join(BG2_PATH, "{}s_{}.png".format(str(star), str(step))) charpic_mask = Image.open(charpic_mask_path) weaponpic_mask = Image.open(weaponpic_mask_path) s5s1 = Image.open(getText(5, 1)) s5s2 = Image.open(getText(5, 2)) s5s3 = Image.open(getText(5, 3)) s5s4 = Image.open(getText(5, 4)) s4s1 = Image.open(getText(4, 1)) s4s2 = Image.open(getText(4, 2)) s4s3 = Image.open(getText(4, 3)) s4s4 = Image.open(getText(4, 4)) s3s3 = Image.open(getText(3, 3)) s2s3 = Image.open(getText(2, 3)) s1s3 = Image.open(getText(1, 3)) char_bg_path = os.path.join(BG2_PATH, "char_bg.png") char_fg_path = os.path.join(BG2_PATH, "char_fg.png") char_bg = Image.open(char_bg_path) char_fg = Image.open(char_fg_path) char_color = (math.floor(bg_color[0] + 10 if bg_color[0] + r <= 255 else 255), math.floor(bg_color[1] + 10 if bg_color[1] + r <= 255 else 255), math.floor(bg_color[2] + 10 if bg_color[2] + r <= 255 else 255)) charset_mask = Image.new("RGBA", (900, 130), char_color) num = 0 char_datas.sort(key=lambda x: (-x['rarity'], -x['level'], -x['friendship'])) if char_num > 8: for i in char_datas: # char_mingzuo = 0 char_name = i["name"] char_id = i["id"] char_level = i["level"] char_fetter = i['friendship'] char_rarity = i['rarity'] # char_weapon_star = i['weapon']['rarity'] # char_weapon_jinglian = i['weapon']['affix_level'] # char_weapon_icon = i['weapon']['icon'] # if not os.path.exists(os.path.join(WEAPON_PATH, str(char_weapon_icon.split('/')[-1]))): # get_weapon_pic(char_weapon_icon) if not os.path.exists(os.path.join(CHAR_PATH, str(i['id']) + ".png")): get_char_pic(i['id'], i['icon']) char = os.path.join(CHAR_PATH, str(char_id) + ".png") # weapon = os.path.join(WEAPON_PATH, str(char_weapon_icon.split('/')[-1])) char_img = Image.open(char) char_img = char_img.resize((100, 100), Image.ANTIALIAS) # weapon_img = Image.open(weapon) # weapon_img = weapon_img.resize((47, 47), Image.ANTIALIAS) charpic = Image.new("RGBA", (125, 140)) if char_rarity == 5: charpic.paste(s5s1, (0, 0), s5s1) baseda = Image.new("RGBA", (100, 100)) cc = Image.composite(char_img, baseda, charpic_mask) charpic.paste(cc, (6, 15), cc) charpic.paste(s5s2, (0, 0), s5s2) # if char_weapon_star == 5: # charpic.paste(s5s3, (0, 0), s5s3) # elif char_weapon_star == 4: # charpic.paste(s4s3, (0, 0), s4s3) # elif char_weapon_star == 3: # charpic.paste(s3s3, (0, 0), s3s3) # elif char_weapon_star == 2: # charpic.paste(s2s3, (0, 0), s2s3) # elif char_weapon_star == 1: # charpic.paste(s1s3, (0, 0), s1s3) basedb = Image.new("RGBA", (47, 47)) # dd = Image.composite(weapon_img, basedb, weaponpic_mask) # charpic.paste(dd, (69, 62), dd) charpic.paste(s5s4, (0, 0), s5s4) else: charpic.paste(s4s1, (0, 0), s4s1) baseda = Image.new("RGBA", (100, 100)) cc = Image.composite(char_img, baseda, charpic_mask) charpic.paste(cc, (6, 15), cc) charpic.paste(s4s2, (0, 0), s4s2) # if char_weapon_star == 5: # charpic.paste(s5s3, (0, 0), s5s3) # elif char_weapon_star == 4: # charpic.paste(s4s3, (0, 0), s4s3) # elif char_weapon_star == 3: # charpic.paste(s3s3, (0, 0), s3s3) # elif char_weapon_star == 2: # charpic.paste(s2s3, (0, 0), s2s3) # elif char_weapon_star == 1: # charpic.paste(s1s3, (0, 0), s1s3) basedb = Image.new("RGBA", (47, 47)) # dd = Image.composite(weapon_img, basedb, weaponpic_mask) # charpic.paste(dd, (69, 62), dd) charpic.paste(s4s4, (0, 0), s4s4) char_draw = ImageDraw.Draw(charpic) char_draw.text((38, 106), f'Lv.{str(char_level)}', (21, 21, 21), ys_font(18)) # 无法读取 char_draw.text((104.5, 91.5), f'{str(char_weapon_jinglian)}', 'white', ys_font(10)) # 无法读取 char_draw.text((99, 19.5), f'{str(char_mingzuo)}', 'white', ys_font(18)) if str(i["friendship"]) == "10" or str(char_name) == "旅行者": char_draw.text((98, 42), "♥", (21, 21, 21), ys_font(14)) else: char_draw.text((100, 41), f'{str(char_fetter)}', (21, 21, 21), ys_font(16)) char_crop = (68 + 129 * (num % 6), 800 + 130 * (num // 6)) bg_img.paste(charpic, char_crop, charpic) num = num + 1 else: for i in char_datas: # char_mingzuo = 0 char_name = i["name"] char_id = i["id"] char_level = i["level"] char_fetter = i['friendship'] char_rarity = i['rarity'] char_img_icon = i["icon"].replace("https://upload-os-bbs.mihoyo.com/game_record/genshin/character_icon/", "https://upload-bbs.mihoyo.com/game_record/genshin/character_image/") char_img_icon = char_img_icon.replace(".png", "@2x.png") # char_weapon_star = i['weapon']['rarity'] # char_weapon_jinglian = i['weapon']['affix_level'] # char_weapon_icon = i['weapon']['icon'] # if not os.path.exists(os.path.join(WEAPON_PATH, str(char_weapon_icon.split('/')[-1]))): # get_weapon_pic(char_weapon_icon) if not os.path.exists(os.path.join(CHAR_IMG_PATH, str(char_img_icon.split('/')[-1]))): get_charimg_pic(char_img_icon) if not os.path.exists(os.path.join(CHAR_PATH, str(i['id']) + ".png")): get_char_pic(i['id'], i['icon']) char = os.path.join(CHAR_PATH, str(char_id) + ".png") # weapon = os.path.join(WEAPON_PATH, str(char_weapon_icon.split('/')[-1])) char_stand_img = os.path.join(CHAR_IMG_PATH, str(char_img_icon.split('/')[-1])) char_stand_mask = Image.open(os.path.join(BG2_PATH, "stand_mask.png")) char_stand = Image.open(char_stand_img) char_img = Image.open(char) char_img = char_img.resize((100, 100), Image.ANTIALIAS) # weapon_img = Image.open(weapon) # weapon_img = weapon_img.resize((47, 47), Image.ANTIALIAS) charpic = Image.new("RGBA", (900, 130)) charpic_temp = Image.new("RGBA", (900, 130)) charpic.paste(charset_mask, (0, 0), char_bg) # weapon_bg = Image.open(getText(char_weapon_star, 3)) # charpic.paste(weapon_bg, (72, 10), weapon_bg) charpic_temp.paste(char_img, (81, 13), charpic_mask) charpic_temp.paste(char_stand, (335, -99), char_stand_mask) charpic_temp.paste(char_fg, (0, 0), char_fg) # charpic_temp.paste(weapon_img, (141, 72), weaponpic_mask) # temp = Image.composite(weapon_img, basedb, weaponpic_mask) charpic.paste(charpic_temp, (0, 0), charpic_temp) # for _, k in enumerate(i["reliquaries"]): # if not os.path.exists(os.path.join(REL_PATH, str(k["icon"].split('/')[-1]))): # get_rel_pic(k["icon"]) # rel = os.path.join(REL_PATH, str(k["icon"].split('/')[-1])) # rel_img = Image.open(rel).resize((43, 43), Image.ANTIALIAS) # rel_bg = Image.open(getText(k["rarity"], 3)) # # if k["pos_name"] == "生之花": # charpic.paste(rel_bg, (287 + 55 * 0, -14), rel_bg) # charpic.paste(rel_img, (360 + 55 * 0, 49), rel_img) # elif k["pos_name"] == "死之羽": # charpic.paste(rel_bg, (287 + 55 * 1, -14), rel_bg) # charpic.paste(rel_img, (360 + 55 * 1, 49), rel_img) # elif k["pos_name"] == "时之沙": # charpic.paste(rel_bg, (287 + 55 * 2, -14), rel_bg) # charpic.paste(rel_img, (360 + 55 * 2, 49), rel_img) # elif k["pos_name"] == "空之杯": # charpic.paste(rel_bg, (287 + 55 * 3, -14), rel_bg) # charpic.paste(rel_img, (360 + 55 * 3, 49), rel_img) # elif k["pos_name"] == "理之冠": # charpic.paste(rel_bg, (287 + 55 * 4, -14), rel_bg) # charpic.paste(rel_img, (360 + 55 * 4, 49), rel_img) char_draw = ImageDraw.Draw(charpic) char_draw.text((182, 39), i["name"], new_color, ys_font(22)) char_draw.text((272, 45), f'Lv.{str(char_level)}', new_color, ys_font(18)) # char_draw.text((104.5,91.5),f'{str(char_weapon_jinglian)}',new_color,ys_font(10)) # char_draw.text((267, 77), f'{str(char_mingzuo)}', new_color, ys_font(18)) char_draw.text((209, 77), f'{str(i["friendship"])}' if str(char_name) != "旅行者" else "10", new_color, ys_font(18)) char_crop = (0, 800 + 110 * num) num += 1 bg_img.paste(charpic, char_crop, charpic) # 转换之后发送 bg_img = bg_img.convert('RGB') bg_img.save(f"temp{os.sep}uid.jpg", format='JPEG', subsampling=0, quality=90) try: if message.media: os.remove(image_data) # noqa except: pass return f"temp{os.sep}uid.jpg" async def draw_wordcloud(uid, message: Message, mode=2): while 1: use_cookies = cacheDB(uid, mode - 1) if use_cookies == '': return "绑定记录不存在。" elif use_cookies == "没有可以使用的Cookies!": return "没有可以使用的Cookies!" if mode == 3: mys_data = await GetMysInfo(uid, use_cookies) uid = mys_data[0]['uid'] raw_Abyss_data = await GetSpiralAbyssInfo(uid, use_cookies) try: raw_data = await GetInfo(uid, use_cookies) except Exception as e: if str(e).find("Cannnot get data for more than 30 accounts per day.") != -1: # return ("当前cookies已达到30人上限!") errorDB(use_cookies, "limit30") continue elif str(e).find("Login cookies have not been provided") != -1: # return ("Cookie错误/过期,请重置Cookie") errorDB(use_cookies, "error") continue else: traceback.print_exc() return ( "Api报错\r\n" + "\r\n出现这种情况可能是UID输入错误 or 不存在" ) break char_datas = raw_data["characters"] # noqa l1_size = 2 l2_size = 4 l3_size = 6 l4_size = 7 l5_size = 10 word_str = {} g3d1 = 0 ly3c = 0 star5num = 0 star5numcon = 0 for i in char_datas: if i["name"] in ['雷电将军', '温迪', '钟离', '枫原万叶']: g3d1 += 1 if i["name"] in ['甘雨', '魈', '胡桃']: ly3c += 1 if i['rarity'] == 5: star5num += 1 if i['name'] != '旅行者': star5numcon += 1 if i["level"] >= 80: if i['name'] == "迪卢克": word_str["落魄了家人们"] = l3_size if i['name'] == "刻晴": word_str["斩尽牛杂"] = l3_size if i['name'] == "旅行者": word_str["旅行者真爱党"] = l3_size game_time = time.mktime(time.strptime('20200915', '%Y%m%d')) now_time = time.time() total_s = now_time - game_time total_d = (((total_s) / 60) / 60) / 24 if math.floor(total_d) - 5 <= raw_data['stats']['active_days']: word_str["开服玩家"] = l4_size if g3d1 >= 4: word_str["三神一帝"] = l3_size if ly3c >= 3: word_str["璃月3C"] = l3_size if star5num >= 16: word_str["五星众多"] = l3_size if raw_data['stats']['anemoculi'] + raw_data['stats']['geoculi'] + raw_data['stats'][ 'electroculi'] == 378: word_str["全神瞳"] = l2_size if raw_data['explorations'][4]['explored'] + \ raw_data['explorations'][3]['explored'] + \ raw_data['explorations'][2]['explored'] + \ raw_data['explorations'][1]['explored'] + \ raw_data['explorations'][0]['explored'] >= 495: word_str["全探索"] = l4_size if raw_data['stats']['achievements'] >= 510: word_str["全成就"] = l5_size elif raw_data['stats']['achievements'] >= 490: word_str["成就达人"] = l3_size if raw_data['stats']['spiral_abyss'] == '12-3': word_str["深境的探究者"] = l2_size if len(raw_data['characters']) >= 42: word_str["全角色"] = l3_size if raw_data['stats']['active_days'] <= 40: word_str["刚入坑"] = l1_size elif raw_data['stats']['active_days'] <= 100: word_str["初心者"] = l2_size elif raw_data['stats']['active_days'] <= 300: word_str["老玩家"] = l2_size if raw_data['stats']['active_days'] >= 365 and raw_data['stats'][ 'common_chests'] + raw_data['stats']['exquisite_chests'] + \ raw_data['stats']['precious_chests'] + raw_data['stats']['luxurious_chests'] <= 2500: word_str["老咸鱼"] = l3_size if raw_data['teapot']: if raw_data['teapot']['comfort'] >= 25000: word_str["团雀附体"] = l2_size if raw_Abyss_data['stats']['total_battles'] <= 12 and raw_Abyss_data['stats']['max_floor'] == '12-3': word_str["PVP资格证"] = l4_size if raw_Abyss_data['character_ranks']['most_damage_taken']: try: if raw_Abyss_data['character_ranks']['most_damage_taken'][0]["value"] >= 150000: word_str["这一击,贯穿星辰"] = l4_size except: pass bg_list = random.choice([x for x in os.listdir(BG_PATH) if os.path.isfile(os.path.join(BG_PATH, x))]) bg2_path = os.path.join(BG_PATH, bg_list) based_w = 900 based_h = 1000 based_scale = '%.3f' % (based_w / based_h) is_edit = False if message.media: is_edit = await message.download() if is_edit: bg_path_edit = is_edit else: bg_path_edit = bg2_path edit_bg = Image.open(bg_path_edit) w, h = edit_bg.size scale_f = '%.3f' % (w / h) new_w = math.ceil(based_h * float(scale_f)) new_h = math.ceil(based_w / float(scale_f)) if scale_f > based_scale: bg_img2 = edit_bg.resize((new_w, based_h), Image.ANTIALIAS) else: bg_img2 = edit_bg.resize((based_w, new_h), Image.ANTIALIAS) bg_img = bg_img2.crop((0, 0, based_w, based_h)) x, y = 50, 153 radius = 50 cropped_img = bg_img.crop((x, y, x + 800, y + 800)) blurred_img = cropped_img.filter(ImageFilter.GaussianBlur(5), ).convert("RGBA") bg_img.paste(blurred_img, (x, y), create_rounded_rectangle_mask(cropped_img, radius)) panle = Image.open(os.path.join(BG2_PATH, 'wordcloud_0.png')) mask = np.array(Image.open(os.path.join(BG2_PATH, 'wordcloudmask.png'))) wc = WordCloud( font_path=os.path.join("assets", "fonts", "ZhuZiAWan-2.ttc"), mask=mask, background_color="rgba(255, 255, 255, 0)", mode="RGBA", max_words=200, max_font_size=80 # color_func=multi_color_func # color_func=similar_color_func ).generate_from_frequencies(word_str, max_font_size=100) image_produce = wc.to_image() bg_img.paste(panle, (0, 0), panle) bg_img.paste(image_produce, (0, 0), image_produce) bg_img = bg_img.convert('RGB') text_draw = ImageDraw.Draw(bg_img) text_draw.text((450, 105), 'UID ' + f"{uid}", (40, 136, 168), ys_font(26), anchor="mm") bg_img.save(f"temp{os.sep}cx.jpg", format='JPEG', subsampling=0, quality=90) if is_edit: try: os.remove(is_edit) except: pass return f"temp{os.sep}cx.jpg"