diff --git a/README.md b/README.md index 2541e29c..2828dcfd 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,14 @@ # GenshinUID / 原神UID查询 -​ 一个HoshinoBot插件,用于查询原神UID信息。 +一个HoshinoBot插件,用于查询原神UID信息,用于查询树脂/探索派遣状态,推送树脂快满了。 -​ 注意:本插件不包含本体,您应该配合[Mrs4s](https://github.com/Mrs4s) / [go-cqhttp](https://github.com/Mrs4s/go-cqhttp) 和 [HoshinoBot](https://github.com/Ice-Cirno/HoshinoBot) 使用,本插件的作用是利用米游社API查询指定原神UID信息(Cookies获取可前往[YuanShen_User_Info](https://github.com/Womsxd/YuanShen_User_Info)查看教程) +**一定要读更新记录和指令!!** -​ 已完成:角色排序(星级>等级>好感),mysid/uid查询,mysid/uid绑定qq号,cookies池,每日自动记录uid查询使用的cookies,下次再查询时仍然调用该cookies(防止浪费),mysid/uid查询深渊单独层数,以上所有输出图片均可支持背景图片自定义。 +注意:本插件不包含本体,您应该配合[Mrs4s](https://github.com/Mrs4s) / [go-cqhttp](https://github.com/Mrs4s/go-cqhttp) 和 [HoshinoBot](https://github.com/Ice-Cirno/HoshinoBot) 使用,本插件的作用是利用米游社API查询指定原神UID信息(Cookies获取可前往[YuanShen_User_Info](https://github.com/Womsxd/YuanShen_User_Info)查看教程) -​ 示例: ![1](https://raw.githubusercontent.com/KimigaiiWuyi/GenshinUID/main/readme/1.PNG) +再次提醒:**Cookies是重要信息,请不要随意泄露!!!** + +示例: ![1](https://raw.githubusercontent.com/KimigaiiWuyi/GenshinUID/main/readme/1.PNG) - [安装](#安装) - [更新记录](#更新记录) @@ -38,12 +40,32 @@ $ pip3 install -r requirements.txt 添加 cookies ``` -注意事项:可以添加多条,但一次只能添加一条,添加两个字的之后必须带有空格,cookies填入你自己的,并且不要泄露给任何人,如果添加了错误的cookies,会导致一系列问题,如果想删除错误的cookies,请操作sqlite数据库完成。 +注意事项:可以添加多条,但一次只能添加一条,添加两个字的之后必须带有空格,cookies填入你自己的,**并且不要泄露给任何人**,~~如果添加了错误的cookies,会导致一系列问题,如果想删除错误的cookies,请操作sqlite数据库完成~~,目前已实现Cookies校验,如果校验失败,请检查Cookies是否按照格式输入。 5、进入机器人在的群聊,即可正常使用本插件。 ## 更新记录 +####2021-10-17 + +**重要:目前Cookies池采用了新的方式,如果你是之前版本的使用者,请在更新后使用群聊命令:迁移Cookies,无损迁移旧版本全部Cookies** + +新增:奇馈宝箱的支持,以及新UI的调整。 + +新增:绑定Cookies可以实现基于当前绑定uid信息的树脂查询,以及推送,具体使用可以前往[指令](#指令)处查阅。 + +新增:可以查询深渊总览信息(beta),具体使用可以前往[指令](#指令)处查阅。 + +新增:可以群内@某人查询(角色信息、深渊总览、深渊固定层数),具体使用可以前往[指令](#指令)处查阅。 + +优化:更换了背景图,更新了readme的指令表格。 + +优化:支持群内命令:校验全部Cookies,以此判断是否Cookies池有失效CK。 + +修复:在查询深渊时背景图片无法正确缩放的问题。 + +修复:极少数情况下,查询功能失效的实例(先uid查询后mys查询)。 + #### 2021-9-27 ​ 新增:Cookies次数防浪费机制(查过的mysid/uid会锁定使用过的cookies,当天再查时会使用同样的cookies防止次数浪费,每日零点清空。) @@ -80,16 +102,10 @@ $ pip3 install -r requirements.txt ​ uid命令现在可以根据角色数量自动设定长宽,并且自定义背景仍然适用!并且添加了角色当前携带的武器ui界面。 -​ ![8](https://raw.githubusercontent.com/KimigaiiWuyi/GenshinUID/main/readme/8.PNG) - ​ UID命令在uid命令的基础上删除了武器的ui界面。 -​ ![7](https://raw.githubusercontent.com/KimigaiiWuyi/GenshinUID/main/readme/7.PNG) - ​ 添加了深渊查询,指令:uidxxxxxx深渊xx,例如uid123456789深渊12,只能查指定楼层(beta) -​ ![9](https://raw.githubusercontent.com/KimigaiiWuyi/GenshinUID/main/readme/9.PNG) - ​ 删除角色命令。 #### 2021-8-14 @@ -130,37 +146,39 @@ $ pip3 install -r requirements.txt ## 指令 -1、仅私聊状态下生效,触发词添加 后跟cookies即可添加Cookies(添加两字后需要带空格) +(**括号内为可选词缀**,以下所有可以输出图片的,**命令后跟图可自定义背景图片**): -![10](https://raw.githubusercontent.com/KimigaiiWuyi/GenshinUID/main/readme/10.png) +| 触发前缀 | 触发后缀/备注 | 效果 | 举例 | 备注 | +| :--------------------- | ---------------------- | ---------------------------------- | ------------------ | ---------------------------------------- | +| uid | | 获取角色信息一览(带武器信息) | uid123456789 | | +| uid | (上期)深渊 | 获取角色深渊总览(层数为最后一层) | uid123456789深渊 | | +| uid | (上期)深渊9/10/11/12 | 获取角色深渊某一层数据 | uid123456789深渊12 | | +| mys | | 角色信息(带武器信息,冒险等级) | mys123456 | 米游社通行证 | +| mys | (上期)深渊 | 获取角色深渊总览(层数为最后一层) | mys123456深渊 | 米游社通行证 | +| mys | (上期)深渊9/10/11/12 | 获取角色深渊某一层数据 | mys123456深渊12 | 米游社通行证 | +| UID | | 获取角色信息一览(不带武器信息) | UID123456789 | 旧版本,比例更和谐 | +| 绑定uid | | 当前qq号关联绑定uid | 绑定uid123456789 | 查询前缀前置条件 | +| 绑定mys | | 当前qq号关联绑定米游社通行证 | 绑定mys12345678 | 查询前缀前置条件 | +| 查询 | | 查询当前绑定角色信息一览 | 查询 | **必须**绑定过mys/uid | +| 查询(上期)深渊 | | 查询当前绑定角色深渊总览 | 查询深渊 | **必须**绑定过mys/uid | +| 查询(上期)深渊\d | | 查询当前绑定角色深渊某一层数据 | 查询深渊10 | **必须**绑定过mys/uid | +| 添加 | | 向cookies池添加cookies | 添加 _ga=balabala | **私聊**bot,注意空格 | +| 查询 @人 | | 获取@的群友的角色信息一览 | 查询 @Wuyi | | +| 查询(上期)深渊 @人 | | 获取@的群友的深渊信息一览 | 查询深渊 @Wuyi | | +| 查询(上期)深渊\d @人 | | 获取@的群友的深渊某一层数据 | 查询深渊10 @Wuyi | | +| 当前状态 | | 获取树脂、每日委托、派遣等信息 | 当前状态 | **必须**绑定过CK和uid | +| 开启推送 | | 开启推送,超过140树脂提醒旅行者 | 开启推送 | 群聊/私聊都可
**必须**绑定过CK和uid | +| 关闭推送 | | 关闭树脂快满的提醒 | 关闭推送 | 都可以 | +| 校验全部Cookies | | 校验当前池内全部Cookies状态 | 校验全部Cookies | **群聊** | +| 迁移Cookies | | 迁移旧版本全部Cookies | 迁移Cookies | **群聊** | -2、群聊状态下生效,绑定uid/绑定mys后跟uid/mysid即可完成绑定 +###深渊查询: -![11](https://raw.githubusercontent.com/KimigaiiWuyi/GenshinUID/main/readme/11.png) - -3、群聊状态下生效,而且必须绑定过uid/mysid才可生效,输出查询可以获取角色图 - -![12](https://raw.githubusercontent.com/KimigaiiWuyi/GenshinUID/main/readme/12.png) - -4、群聊状态下生效,而且必须绑定过uid/mysid才可生效,输出查询深渊xx可以获取当期深渊层数图 - -![13](https://raw.githubusercontent.com/KimigaiiWuyi/GenshinUID/main/readme/13.png) - -5、群聊状态下生效,触发词uid后面跟九位uid即可/触发词mys后面跟米游社通行证即可。 - -![2](https://raw.githubusercontent.com/KimigaiiWuyi/GenshinUID/main/readme/2.png) - -6、群聊状态下生效,mysid/uid后跟相应数字后跟深渊后跟相应层数即可。 - -![14](https://raw.githubusercontent.com/KimigaiiWuyi/GenshinUID/main/readme/14.png) - -7、以上所有可输出图片的触发词后跟一张任意大小的图片(不能是GIF),可以自定义背景 - -![3](https://raw.githubusercontent.com/KimigaiiWuyi/GenshinUID/main/readme/3.png) - -![4](https://raw.githubusercontent.com/KimigaiiWuyi/GenshinUID/main/readme/4.png) +![2](https://raw.githubusercontent.com/KimigaiiWuyi/GenshinUID/main/readme/2.PNG) +###当前状态: +![3](https://raw.githubusercontent.com/KimigaiiWuyi/GenshinUID/main/readme/3.PNG) ## 相关仓库 diff --git a/__init__.py b/__init__.py index eaeb6b65..b2b0b34f 100644 --- a/__init__.py +++ b/__init__.py @@ -1,32 +1,17 @@ -import re - -#from nonebot import on_command -#from nonebot.adapters.cqhttp import Event, Bot, Message - -from .getImg import draw_pic,draw_abyss_pic -from .getData import GetMysInfo -from .getDB import connectDB,selectDB,cookiesDB,cacheDB,deletecache +from .getImg import draw_pic,draw_abyss_pic,draw_abyss0_pic +from .getDB import connectDB,selectDB,cookiesDB,cacheDB,deletecache,CheckDB,TransDB,OpenPush,GetMysInfo,GetDaily from nonebot import * -import json -from random import randint -import requests,random,os,json,re from hoshino import Service,R,priv,util from hoshino.typing import MessageSegment,CQEvent, HoshinoBot -from hoshino.util import FreqLimiter,pic2b64 + +import requests,random,os,json,re,time,datetime,string,base64 + import hoshino import asyncio -import time -import datetime -import string -import random import hashlib -import requests -import os -from PIL import Image,ImageFont,ImageDraw +import sqlite3 from io import BytesIO -import base64 - import urllib sv = Service('genshinuid') @@ -41,16 +26,176 @@ Texture_PATH = os.path.join(FILE2_PATH,'texture2d') async def delete(): deletecache() +@sv.scheduled_job('interval', minutes=30) +async def push(): + conn = sqlite3.connect('ID_DATA.db') + c = conn.cursor() + cursor = c.execute("SELECT * FROM NewCookies WHERE StatusA != ?",("off",)) + c_data = cursor.fetchall() + for row in c_data: + raw_data = await GetDaily(str(row[1])) + dailydata = raw_data["data"] + resin_num = dailydata["current_resin"] + if resin_num >= row[5]: + re_time = dailydata["resin_recovery_time"] + m, s = divmod(int(re_time), 60) + h, m = divmod(m, 60) + time = "%02d小时%02d分钟%02d秒" % (h, m, s) + + task_num = dailydata["finished_task_num"] + travel_num = dailydata["current_expedition_num"] + max_travel_num = dailydata["max_expedition_num"] + travel_data = dailydata["expeditions"] + + travel_str = '' + + for i in travel_data: + name = i["avatar_side_icon"].split('/')[-1].split('.')[0].split('_')[-1] + statu = i['status'] + if statu == "Finished": + travel_str = travel_str + f"{name} : 完成\n" + else: + remain_time = i['remained_time'] + m1, s1 = divmod(int(remain_time), 60) + h1, m1 = divmod(m1, 60) + remain_time_str = "还剩%02d小时%02d分钟%02d秒" % (h1, m1, s1) + travel_str = travel_str + f"{name} : {remain_time_str}\n" + im = f''' +============== +你的树脂快满了!!! +(还剩{time}补充满) +============== +原粹树脂:{resin_num}/160 +每日委托:{task_num}/4 +探索派遣:{travel_num}/{max_travel_num} +======== +{travel_str} +'''.strip() + + if row[2] == "on": + await bot.send_private_msg(user_id = row[4],message = im) + else: + await bot.send_group_msg(group_id = row[2],message = f"[CQ:at,qq={row[4]}]" + "\n" + im) + else: + pass + @bot.on_message('private') async def setting(ctx): message = ctx['raw_message'] sid=int(ctx["self_id"]) - uid=int(ctx["sender"]["user_id"]) + userid=int(ctx["sender"]["user_id"]) gid=0 if '添加 ' in message: - mes = message.replace('添加 ','') - await cookiesDB(mes) - await bot.send_msg(self_id=sid, user_id=uid, group_id=gid, message=f'添加cookies成功!') + try: + mes = message.replace('添加 ','') + ltuid = re.search(r"ltuid=(\d*)", mes) + mysid_data = ltuid.group(0).split('=') + mysid = mysid_data[1] + + mys_data = await GetMysInfo(mysid,mes) + mys_data = mys_data[0] + uid = mys_data['data']['list'][0]['game_role_id'] + + await cookiesDB(uid,mes) + await bot.send_msg(self_id=sid, user_id=userid, group_id=gid, message=f'添加Cookies成功!Cookies属于个人重要信息,如果你是在不知情的情况下添加,请马上修改米游社账户密码,保护个人隐私!') + except: + await bot.send_msg(self_id=sid, user_id=userid, group_id=gid, message=f'校验失败!') + elif '开启推送' in message: + try: + uid = await selectDB(userid,mode = "uid") + im = await OpenPush(int(uid[0]),userid,"on") + await bot.send_msg(self_id=sid, user_id=userid, group_id=gid, message=im) + except: + await bot.send_msg(self_id=sid, user_id=userid, group_id=gid, message="未找到uid绑定记录。") + elif '关闭推送' in message: + try: + uid = await selectDB(userid,mode = "uid") + im = await OpenPush(int(uid[0]),userid,"off") + await bot.send_msg(self_id=sid, user_id=userid, group_id=gid, message=im) + except: + await bot.send_msg(self_id=sid, user_id=userid, group_id=gid, message="未找到uid绑定记录。") + +@sv.on_fullmatch('开启推送') +async def _(bot:HoshinoBot, ev: CQEvent): + try: + gid = ev.group_id + qid = ev.sender["user_id"] + uid = await selectDB(ev.sender['user_id'],mode = "uid") + im = await OpenPush(int(uid[0]),ev.sender['user_id'],str(gid)) + await bot.send(ev,im,at_sender=True) + except: + await bot.send(ev,"未绑定uid信息!",at_sender=True) + +@sv.on_fullmatch('关闭推送') +async def _(bot:HoshinoBot, ev: CQEvent): + try: + gid = ev.group_id + qid = ev.sender["user_id"] + uid = await selectDB(ev.sender['user_id'],mode = "uid") + im = await OpenPush(int(uid[0]),ev.sender['user_id'],"off") + await bot.send(ev,im,at_sender=True) + except: + await bot.send(ev,"未绑定uid信息!",at_sender=True) + +@sv.on_fullmatch('校验全部Cookies') +async def _(bot:HoshinoBot, ev: CQEvent): + im = await CheckDB() + await bot.send(ev,im) + +@sv.on_fullmatch('迁移Cookies') +async def _(bot:HoshinoBot, ev: CQEvent): + im = await TransDB() + await bot.send(ev,im) + +@sv.on_fullmatch('当前状态') +async def _(bot:HoshinoBot, ev: CQEvent): + try: + uid = await selectDB(ev.sender['user_id'],mode = "uid") + uid = uid[0] + raw_data = await GetDaily(uid) + dailydata = raw_data["data"] + resin_num = dailydata["current_resin"] + re_time = dailydata["resin_recovery_time"] + m, s = divmod(int(re_time), 60) + h, m = divmod(m, 60) + time = "%02d小时%02d分钟%02d秒" % (h, m, s) + + task_num = dailydata["finished_task_num"] + travel_num = dailydata["current_expedition_num"] + max_travel_num = dailydata["max_expedition_num"] + travel_data = dailydata["expeditions"] + + travel_str = '' + + for i in travel_data: + name = i["avatar_side_icon"].split('/')[-1].split('.')[0].split('_')[-1] + statu = i['status'] + if statu == "Finished": + travel_str = travel_str + f"{name} : 完成\n" + else: + remain_time = i['remained_time'] + m1, s1 = divmod(int(remain_time), 60) + h1, m1 = divmod(m1, 60) + remain_time_str = "还剩%02d小时%02d分钟%02d秒" % (h1, m1, s1) + travel_str = travel_str + f"{name} : {remain_time_str}\n" + + im = f''' +: +============== +(还剩{time}补充满) +============== +原粹树脂:{resin_num}/160 +每日委托:{task_num}/4 +探索派遣:{travel_num}/{max_travel_num} +======== +{travel_str} +'''.strip() + + except: + im = "没有找到绑定信息。" + + await bot.send(ev,im, at_sender=True) + @sv.on_prefix('uid') async def _(bot:HoshinoBot, ev: CQEvent): @@ -60,11 +205,26 @@ async def _(bot:HoshinoBot, ev: CQEvent): m = ''.join(re.findall('[\u4e00-\u9fa5]',message)) if m == "深渊": try: - floor_num = re.findall(r"\d+", message)[1] - im = await draw_abyss_pic(uid,ev.sender['nickname'],floor_num,image) - await bot.send(ev, im, at_sender=True) + if len(re.findall(r"\d+", message)) == 2: + floor_num = re.findall(r"\d+", message)[1] + im = await draw_abyss_pic(uid,ev.sender['nickname'],floor_num,image) + await bot.send(ev, im, at_sender=True) + else: + im = await draw_abyss0_pic(uid,ev.sender['nickname'],image) + await bot.send(ev, im, at_sender=True) except: await bot.send(ev,'深渊输入错误!') + elif m == "上期深渊": + try: + if len(re.findall(r"\d+", message)) == 2: + floor_num = re.findall(r"\d+", message)[1] + im = await draw_abyss_pic(uid,ev.sender['nickname'],floor_num,image,2,"2") + await bot.send(ev, im, at_sender=True) + else: + im = await draw_abyss0_pic(uid,ev.sender['nickname'],image,2,"2") + await bot.send(ev, im, at_sender=True) + except: + await bot.send(ev,'深渊输入错误!') else: try: im = await draw_pic(uid,ev.sender['nickname'],image,2) @@ -87,22 +247,46 @@ async def _(bot:HoshinoBot, ev: CQEvent): await bot.send(ev,'绑定米游社id成功!', at_sender=True) @sv.on_prefix('查询') -async def _(bot:HoshinoBot, ev: CQEvent): +async def _(bot, ev): image = re.search(r"\[CQ:image,file=(.*),url=(.*)\]", str(ev.message)) + at = re.search(r"\[CQ:at,qq=(\d*)\]", str(ev.raw_message.strip())) message = ev.message.extract_plain_text() - uid = await selectDB(ev.sender['user_id']) + if at: + qid = at.group(1) + mi =await bot.get_group_member_info(group_id=ev.group_id, user_id=qid) + nickname = mi["nickname"] + uid = await selectDB(qid) + else: + nickname = ev.sender['nickname'] + uid = await selectDB(ev.sender['user_id']) + m = ''.join(re.findall('[\u4e00-\u9fa5]',message)) if uid: if m == "深渊": try: - floor_num = re.findall(r"\d+", message)[0] - im = await draw_abyss_pic(uid[0],ev.sender['nickname'],floor_num,image,uid[1]) - await bot.send(ev, im, at_sender=True) + if len(re.findall(r"\d+", message)) == 1: + floor_num = re.findall(r"\d+", message)[0] + im = await draw_abyss_pic(uid[0],nickname,floor_num,image,uid[1]) + await bot.send(ev, im, at_sender=True) + else: + im = await draw_abyss0_pic(uid[0],nickname,image,uid[1]) + await bot.send(ev, im, at_sender=True) except: await bot.send(ev,'输入错误!') + elif m == "上期深渊": + try: + if len(re.findall(r"\d+", message)) == 1: + floor_num = re.findall(r"\d+", message)[0] + im = await draw_abyss_pic(uid[0],nickname,floor_num,image,uid[1],"2") + await bot.send(ev, im, at_sender=True) + else: + im = await draw_abyss0_pic(uid[0],nickname,image,uid[1],"2") + await bot.send(ev, im, at_sender=True) + except: + await bot.send(ev,'深渊输入错误!') elif m == "": try: - bg = await draw_pic(uid[0],ev.sender['nickname'],image,uid[1]) + bg = await draw_pic(uid[0],nickname,image,uid[1]) await bot.send(ev, bg, at_sender=True) except: await bot.send(ev,'输入错误!') @@ -120,11 +304,26 @@ async def _(bot:HoshinoBot, ev: CQEvent): m = ''.join(re.findall('[\u4e00-\u9fa5]',message)) if m == "深渊": try: - floor_num = re.findall(r"\d+", message)[1] - im = await draw_abyss_pic(uid,ev.sender['nickname'],floor_num,image,3) - await bot.send(ev, im, at_sender=True) + if len(re.findall(r"\d+", message)) == 2: + floor_num = re.findall(r"\d+", message)[1] + im = await draw_abyss_pic(uid,ev.sender['nickname'],floor_num,image,3) + await bot.send(ev, im, at_sender=True) + else: + im = await draw_abyss0_pic(uid,ev.sender['nickname'],image,3) + await bot.send(ev, im, at_sender=True) except: await bot.send(ev,'深渊输入错误!') + elif m == "上期深渊": + try: + if len(re.findall(r"\d+", message)) == 1: + floor_num = re.findall(r"\d+", message)[0] + im = await draw_abyss_pic(uid,ev.sender['nickname'],floor_num,image,3,"2") + await bot.send(ev, im, at_sender=True) + else: + im = await draw_abyss0_pic(uid,ev.sender['nickname'],image,3,"2") + await bot.send(ev, im, at_sender=True) + except: + await bot.send(ev,'深渊输入错误!') else: try: im = await draw_pic(uid,ev.sender['nickname'],image,3) diff --git a/getDB.py b/getDB.py index 2de7847c..64e5180e 100644 --- a/getDB.py +++ b/getDB.py @@ -1,11 +1,98 @@ import sqlite3 -import os -import yaml -import random +import sys + +from httpx import AsyncClient + +from nonebot import * +import requests,random,os,json,re +import hoshino +import asyncio +import time +import string +import hashlib +import base64 + +mhyVersion = "2.11.1" FILE_PATH = os.path.abspath(os.path.join(os.getcwd(), "hoshino")) DATA_PATH = os.path.join(FILE_PATH,'config') +async def OpenPush(uid,qid,status): + conn = sqlite3.connect('ID_DATA.db') + c = conn.cursor() + cursor = c.execute("SELECT * from NewCookies WHERE UID = ?",(uid,)) + c_data = cursor.fetchall() + if len(c_data) != 0: + try: + c.execute("UPDATE NewCookies SET StatusA = ?,QID = ? WHERE UID=?",(status,qid,uid)) + conn.commit() + conn.close() + return "成功!" + except: + return "未找到Ck绑定记录。" + else: + return "未找到Ck绑定记录。" + +async def CheckDB(): + str = '' + conn = sqlite3.connect('ID_DATA.db') + c = conn.cursor() + cursor = c.execute("SELECT Cookies,UID from NewCookies") + for row in cursor: + try: + ltuid = re.search(r"ltuid=(\d*)", row[0]) + mysid_data = ltuid.group(0).split('=') + mysid = mysid_data[1] + + mys_data = await GetMysInfo(mysid,row[0]) + mys_data = mys_data[0] + uid = mys_data['data']['list'][0]['game_role_id'] + + str = str + f"uid{row[1]}/mysid{mysid}的Cookies是正常的!\n" + except: + str = str + f"uid{row[1]}/mysid{mysid}的Cookies是异常的!已删除该条Cookies!\n" + c.execute("DELETE from NewCookies where UID=?",(row[1],)) + conn.commit() + conn.close() + return str + +async def TransDB(): + str = '' + conn = sqlite3.connect('ID_DATA.db') + c = conn.cursor() + test = c.execute("SELECT count(*) FROM sqlite_master WHERE type='table' AND name = 'CookiesTable'") + if test == 0: + conn.commit() + conn.close() + return "你没有需要迁移的数据库。" + else: + c.execute('''CREATE TABLE IF NOT EXISTS NewCookies + (Cookies TEXT PRIMARY KEY NOT NULL, + UID INT, + StatusA TEXT, + StatusB TEXT, + QID INT, + NUM INT, + Extra TEXT);''') + cursor = c.execute("SELECT * from CookiesTable") + c_data = cursor.fetchall() + for row in c_data: + try: + ltuid = re.search(r"ltuid=(\d*)", row[0]) + mysid_data = ltuid.group(0).split('=') + mysid = mysid_data[1] + mys_data = await GetMysInfo(mysid,row[0]) + mys_data = mys_data[0] + uid = mys_data['data']['list'][0]['game_role_id'] + c.execute("INSERT OR IGNORE INTO NewCookies (Cookies,UID,StatusA,StatusB,NUM) \ + VALUES (?, ?,?,?,?)",(row[0],uid,"off","off",140)) + str = str + f"uid{uid}/mysid{mysid}的Cookies已转移成功!\n" + except: + str = str + f"uid{uid}/mysid{mysid}的Cookies是异常的!已删除该条Cookies!\n" + conn.commit() + conn.close() + return str + async def connectDB(userid,uid = None,mys = None): conn = sqlite3.connect('ID_DATA.db') c = conn.cursor() @@ -25,20 +112,25 @@ async def connectDB(userid,uid = None,mys = None): conn.commit() conn.close() -async def selectDB(userid): +async def selectDB(userid,mode = "auto"): conn = sqlite3.connect('ID_DATA.db') c = conn.cursor() cursor = c.execute("SELECT * FROM UIDDATA WHERE USERID = ?",(userid,)) for row in cursor: - if row[0]: - if row[2]: - return [row[2],3] - elif row[1]: - return [row[1],2] + if mode == "auto": + if row[0]: + if row[2]: + return [row[2],3] + elif row[1]: + return [row[1],2] + else: + return None else: return None - else: - return None + elif mode == "uid": + return [row[1],2] + elif mode == "mys": + return [row[2],3] def deletecache(): conn = sqlite3.connect('ID_DATA.db') @@ -68,9 +160,7 @@ async def cacheDB(uid,mode = 1,mys = None): c_data = cursor.fetchall() if len(c_data)==0: - cookiesrow = c.execute("SELECT * FROM CookiesTable ORDER BY RANDOM() limit 1") - #r = cookiesrow.fetchall() - #random.randint(0,len(r)) + cookiesrow = c.execute("SELECT * FROM NewCookies ORDER BY RANDOM() limit 1") for row2 in cookiesrow: if mode == 1: c.execute("INSERT OR IGNORE INTO CookiesCache (Cookies,UID) \ @@ -82,20 +172,180 @@ async def cacheDB(uid,mode = 1,mys = None): else: use = c_data[0][2] if mys: - c.execute("UPDATE CookiesCache SET UID = ? WHERE MYSID=?",(uid,mys)) + try: + c.execute("UPDATE CookiesCache SET UID = ? WHERE MYSID=?",(uid,mys)) + except: + c.execute("UPDATE CookiesCache SET MYSID = ? WHERE UID=?",(mys,uid)) conn.commit() conn.close() return use -async def cookiesDB(Cookies): +async def cookiesDB(uid,Cookies): conn = sqlite3.connect('ID_DATA.db') c = conn.cursor() - c.execute('''CREATE TABLE IF NOT EXISTS CookiesTable - (Cookies TEXT PRIMARY KEY NOT NULL);''') - c.execute("INSERT OR IGNORE INTO CookiesTable (Cookies) \ - VALUES (?)",(Cookies,)) + c.execute('''CREATE TABLE IF NOT EXISTS NewCookies + (Cookies TEXT PRIMARY KEY NOT NULL, + UID INT, + StatusA TEXT, + StatusB TEXT, + QID INT, + NUM INT, + Extra TEXT);''') + + c.execute("INSERT OR IGNORE INTO NewCookies (Cookies,UID,StatusA,StatusB,NUM) \ + VALUES (?, ?,?,?,?)",(Cookies,uid,"off","off",140)) conn.commit() conn.close() + +async def OwnerCookies(uid): + conn = sqlite3.connect('ID_DATA.db') + c = conn.cursor() + + try: + cursor = c.execute("SELECT * FROM NewCookies WHERE UID = ?",(uid,)) + c_data = cursor.fetchall() + cookies = c_data[0][0] + except: + return + + return cookies + + + + + + + + + + + + +def md5(text): + md5 = hashlib.md5() + md5.update(text.encode()) + return md5.hexdigest() + +def DSGet(q = "",b = None): + if b: + br = json.dumps(b) + else: + br = "" + s = "xV8v4Qu54lUKrEYFZkJhB8cuOh9Asafs" + t = str(int(time.time())) + r = str(random.randint(100000, 200000)) + c = md5("salt=" + s + "&t=" + t + "&r=" + r + "&b=" + br + "&q=" + q) + return t + "," + r + "," + c + +async def GetDaily(Uid,ServerID="cn_gf01"): + if Uid[0] == '5': + ServerID = "cn_qd01" + try: + async with AsyncClient() as client: + req = await client.get( + url="https://api-takumi.mihoyo.com/game_record/app/genshin/api/dailyNote?server=" + ServerID + "&role_id=" + Uid, + headers={ + 'DS': DSGet("role_id=" + Uid + "&server=" + ServerID), + 'x-rpc-app_version': mhyVersion, + 'User-Agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 13_2_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) miHoYoBBS/2.11.1', + 'x-rpc-client_type': '5', + 'Referer': 'https://webstatic.mihoyo.com/', + "Cookie": await OwnerCookies(Uid)}) + data = json.loads(req.text) + return data + except: + print("访问失败,请重试!") + sys.exit(1) + +async def GetInfo(Uid,ServerID="cn_gf01",Schedule_type="1",mysid = None): + if Uid[0] == '5': + ServerID = "cn_qd01" + try: + async with AsyncClient() as client: + req = await client.get( + url="https://api-takumi.mihoyo.com/game_record/app/genshin/api/index?role_id=" + Uid + "&server=" + ServerID, + headers={ + 'DS': DSGet("role_id=" + Uid + "&server=" + ServerID), + 'x-rpc-app_version': mhyVersion, + 'User-Agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 13_2_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) miHoYoBBS/2.11.1', + 'x-rpc-client_type': '5', + 'Referer': 'https://webstatic.mihoyo.com/', + "Cookie": await cacheDB(Uid,1,mysid)}) + data = json.loads(req.text) + return data + except: + print("访问失败,请重试!") + sys.exit(1) + +async def GetSpiralAbyssInfo(Uid, ServerID="cn_gf01",Schedule_type="1",mysid = None): + if Uid[0] == '5': + ServerID = "cn_qd01" + try: + async with AsyncClient() as client: + req = await client.get( + url="https://api-takumi.mihoyo.com/game_record/app/genshin/api/spiralAbyss?schedule_type=" + Schedule_type + "&server="+ ServerID +"&role_id=" + Uid, + headers={ + 'DS': DSGet("role_id=" + Uid + "&schedule_type=" + Schedule_type + "&server="+ ServerID), + 'Origin': 'https://webstatic.mihoyo.com', + 'Cookie': await cacheDB(Uid,1,mysid), + 'x-rpc-app_version': mhyVersion, + 'User-Agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 13_2_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) miHoYoBBS/2.11.1', + 'x-rpc-client_type': '5', + 'Referer': 'https://webstatic.mihoyo.com/' + } + ) + data = json.loads(req.text) + return data + except: + print("1访问失败,请重试!") + sys.exit(1) + + +async def GetCharacter(Uid,Character_ids, ServerID="cn_gf01",mysid = None): + if Uid[0] == '5': + ServerID = "cn_qd01" + try: + req = requests.post( + url = "https://api-takumi.mihoyo.com/game_record/app/genshin/api/character", + headers={ + 'DS': DSGet('',{"character_ids": Character_ids ,"role_id": Uid ,"server": ServerID}), + 'Origin': 'https://webstatic.mihoyo.com', + 'Cookie': await cacheDB(Uid,1,mysid), + 'x-rpc-app_version': mhyVersion, + 'User-Agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 13_2_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) miHoYoBBS/2.11.1', + 'x-rpc-client_type': '5', + 'Referer': 'https://webstatic.mihoyo.com/' + }, + json = {"character_ids": Character_ids ,"role_id": Uid ,"server": ServerID} + ) + data2 = json.loads(req.text) + return data2 + except: + print("访问失败,请重试!") + sys.exit(1) + +async def GetMysInfo(mysid,cookies = None): + if cookies: + ck = cookies + else: + ck = await cacheDB(mysid,2) + try: + async with AsyncClient() as client: + req = await client.get( + url="https://api-takumi.mihoyo.com/game_record/card/wapi/getGameRecordCard?uid=" + mysid, + headers={ + 'DS': DSGet("uid="+mysid), + 'x-rpc-app_version': mhyVersion, + 'User-Agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 13_2_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) miHoYoBBS/2.11.1', + 'x-rpc-client_type': '5', + 'Referer': 'https://webstatic.mihoyo.com/', + "Cookie": ck}) + data = json.loads(req.text) + return [data,mysid] + except: + print ("访问失败,请重试!") + #sys.exit (1) + return \ No newline at end of file diff --git a/getData.py b/getData.py deleted file mode 100644 index c7524a04..00000000 --- a/getData.py +++ /dev/null @@ -1,151 +0,0 @@ -# https://github.com/Womsxd/YuanShen_User_Info -#import hashlib -#import json -#import random -#import string -import sys -#import time - -from httpx import AsyncClient - -from .getDB import cookiesDB,cacheDB - -from nonebot import * -import json -from random import randint -import requests,random,os,json,re -from hoshino import Service,R,priv,util -from hoshino.typing import MessageSegment,CQEvent, HoshinoBot -from hoshino.util import FreqLimiter,pic2b64 -import hoshino -import asyncio -import time -import string -import random -import hashlib -import requests -import os -from PIL import Image,ImageFont,ImageDraw -from io import BytesIO -import base64 - -mhyVersion = "2.11.1" - -def md5(text): - md5 = hashlib.md5() - md5.update(text.encode()) - return md5.hexdigest() - -def DSGet(q = "",b = None): - if b: - br = json.dumps(b) - else: - br = "" - s = "xV8v4Qu54lUKrEYFZkJhB8cuOh9Asafs" - t = str(int(time.time())) - r = str(random.randint(100000, 200000)) - c = md5("salt=" + s + "&t=" + t + "&r=" + r + "&b=" + br + "&q=" + q) - return t + "," + r + "," + c - -async def GetInfo(Uid,ServerID="cn_gf01",Schedule_type="1",mysid = None): - if Uid[0] == '5': - ServerID = "cn_qd01" - try: - async with AsyncClient() as client: - req = await client.get( - url="https://api-takumi.mihoyo.com/game_record/app/genshin/api/index?role_id=" + Uid + "&server=" + ServerID, - headers={ - #'Accept': 'application/json, text/plain, */*', - 'DS': DSGet("role_id=" + Uid + "&server=" + ServerID), - #'Origin': 'https://webstatic.mihoyo.com', - 'x-rpc-app_version': mhyVersion, - 'User-Agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 13_2_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) miHoYoBBS/2.11.1', - 'x-rpc-client_type': '5', - 'Referer': 'https://webstatic.mihoyo.com/', - #'Accept-Encoding': 'gzip, deflate', - #'Accept-Language': 'zh-CN,en-US;q=0.8', - #'X-Requested-With': 'com.mihoyo.hyperion', - "Cookie": await cacheDB(Uid,1,mysid)}) - data = json.loads(req.text) - return data - except: - print("访问失败,请重试!") - sys.exit(1) - -async def GetSpiralAbyssInfo(Uid, ServerID="cn_gf01",Schedule_type="1",mysid = None): - if Uid[0] == '5': - ServerID = "cn_qd01" - try: - async with AsyncClient() as client: - req = await client.get( - url="https://api-takumi.mihoyo.com/game_record/app/genshin/api/spiralAbyss?schedule_type=" + Schedule_type + "&server="+ ServerID +"&role_id=" + Uid, - headers={ - 'Accept': 'application/json, text/plain, */*', - 'DS': DSGet("role_id=" + Uid + "&schedule_type=" + Schedule_type + "&server="+ ServerID), - 'Origin': 'https://webstatic.mihoyo.com', - 'Cookie': await cacheDB(Uid,1,mysid), - 'x-rpc-app_version': mhyVersion, - 'User-Agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 13_2_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) miHoYoBBS/2.11.1', - 'x-rpc-client_type': '5', - 'Referer': 'https://webstatic.mihoyo.com/', - 'Accept-Encoding': 'gzip, deflate', - 'Accept-Language': 'zh-CN,en-US;q=0.8', - 'X-Requested-With': 'com.mihoyo.hyperion' - } - ) - data = json.loads(req.text) - return data - except: - print("1访问失败,请重试!") - sys.exit(1) - - -async def GetCharacter(Uid,Character_ids, ServerID="cn_gf01",mysid = None): - if Uid[0] == '5': - ServerID = "cn_qd01" - try: - req = requests.post( - url = "https://api-takumi.mihoyo.com/game_record/app/genshin/api/character", - headers={ - 'Accept': 'application/json, text/plain, */*', - 'DS': DSGet('',{"character_ids": Character_ids ,"role_id": Uid ,"server": ServerID}), - 'Origin': 'https://webstatic.mihoyo.com', - 'Cookie': await cacheDB(Uid,1,mysid), - 'x-rpc-app_version': mhyVersion, - 'User-Agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 13_2_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) miHoYoBBS/2.11.1', - 'x-rpc-client_type': '5', - 'Referer': 'https://webstatic.mihoyo.com/', - 'Accept-Encoding': 'gzip, deflate', - 'Accept-Language': 'zh-CN,en-US;q=0.8', - 'X-Requested-With': 'com.mihoyo.hyperion' - }, - json = {"character_ids": Character_ids ,"role_id": Uid ,"server": ServerID} - ) - data2 = json.loads(req.text) - return data2 - except: - print("访问失败,请重试!") - sys.exit(1) - -async def GetMysInfo(mysid): - try: - async with AsyncClient() as client: - req = await client.get( - url="https://api-takumi.mihoyo.com/game_record/card/wapi/getGameRecordCard?uid=" + mysid, - headers={ - #'Accept': 'application/json, text/plain, */*', - 'DS': DSGet("uid="+mysid), - #'Origin': 'https://webstatic.mihoyo.com', - 'x-rpc-app_version': mhyVersion, - 'User-Agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 13_2_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) miHoYoBBS/2.11.1', - 'x-rpc-client_type': '5', - 'Referer': 'https://webstatic.mihoyo.com/', - #'Accept-Encoding': 'gzip, deflate', - #'Accept-Language': 'zh-CN,en-US;q=0.8', - #'X-Requested-With': 'com.mihoyo.hyperion', - "Cookie": await cacheDB(mysid,2)}) - data = json.loads(req.text) - return [data,mysid] - except: - print ("访问失败,请重试!") - return \ No newline at end of file diff --git a/getImg.py b/getImg.py index 0936c758..c069bb3f 100644 --- a/getImg.py +++ b/getImg.py @@ -7,7 +7,7 @@ import math from PIL import Image, ImageDraw, ImageFont, ImageFilter -from .getData import GetInfo,GetCharacter,GetSpiralAbyssInfo,GetMysInfo +from .getDB import GetInfo,GetCharacter,GetSpiralAbyssInfo,GetMysInfo import os import json @@ -57,14 +57,7 @@ def get_chardone_pic(id,url,star): def get_weapon_pic(url): urllib.request.urlretrieve(url, os.path.join(WEAPON_PATH, url.split('/')[-1])) -async def draw_abyss_pic(uid,nickname,floor_num,image = None,mode = 2): - is_edit = False - if image != None: - image_file= image.group(1) - image_data = image.group(2) - urllib.request.urlretrieve(f'{image_data}', os.path.join(TEXT_PATH,nickname + '.png')) - is_edit = True - +async def draw_abyss0_pic(uid,nickname,image = None,mode = 2,date = "1"): if mode == 3: mys_data = await GetMysInfo(uid) mysid_data = mys_data[1] @@ -73,11 +66,11 @@ async def draw_abyss_pic(uid,nickname,floor_num,image = None,mode = 2): nickname = mys_data['data']['list'][0]['nickname'] #role_region = mys_data['data']['list'][0]['region'] role_level = mys_data['data']['list'][0]['level'] - raw_data = await GetSpiralAbyssInfo(uid,"cn_gf01","1",mysid_data) - raw_char_data = await GetInfo(uid,"cn_gf01","1",mysid_data) + raw_data = await GetSpiralAbyssInfo(uid,"cn_gf01",date,mysid_data) + raw_char_data = await GetInfo(uid,"cn_gf01",date,mysid_data) else: - raw_data = await GetSpiralAbyssInfo(uid) - raw_char_data = await GetInfo(uid) + raw_data = await GetSpiralAbyssInfo(uid,"cn_gf01",date) + raw_char_data = await GetInfo(uid,"cn_gf01",date) if (raw_data["retcode"] != 0): if (raw_data["retcode"] == 10001): @@ -96,6 +89,295 @@ async def draw_abyss_pic(uid,nickname,floor_num,image = None,mode = 2): raw_data = raw_data["data"] raw_char_data = raw_char_data['data']["avatars"] + is_edit = False + if image != None: + image_file= image.group(1) + image_data = image.group(2) + urllib.request.urlretrieve(f'{image_data}', os.path.join(TEXT_PATH,nickname + '.png')) + is_edit = True + + 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) + + abyss0_path = os.path.join(TEXT_PATH,"abyss_0.png") + abyss2_path = os.path.join(TEXT_PATH,"abyss_2.png") + abyss3_path = os.path.join(TEXT_PATH,"abyss_3.png") + abyss_star0_path = os.path.join(TEXT_PATH,"abyss_star0.png") + abyss_star1_path = os.path.join(TEXT_PATH,"abyss_star1.png") + + floors_data = raw_data['floors'][-1] + levels_num = len(floors_data['levels']) + + based_w = 900 + based_h = 880+levels_num*315 + based_scale = '%.3f' % (based_w/based_h) + + if is_edit == True: + bg_path_edit = os.path.join(TEXT_PATH,f"{nickname}.png") + 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)) + + x1, y1 = 45, 271 + radius = 10 + cropped_img1 = bg_img.crop((x1, y1, 857, 831)) + blurred_img1 = cropped_img1.filter(ImageFilter.GaussianBlur(5),).convert("RGBA") + bg_img.paste(blurred_img1, (x1, y1), create_rounded_rectangle_mask(cropped_img1,radius)) + + for i in range(0,len(floors_data['levels'])): + x2, y2 = 45, 850 + 315*i + radius = 10 + cropped_img2 = bg_img.crop((x2, y2, 855, 1145+315*i)) + blurred_img2 = cropped_img2.filter(ImageFilter.GaussianBlur(5),).convert("RGBA") + bg_img.paste(blurred_img2, (x2, y2), create_rounded_rectangle_mask(cropped_img2,radius)) + + abyss0 = Image.open(abyss0_path) + abyss3 = Image.open(abyss3_path) + abyss_star0 = Image.open(abyss_star0_path) + abyss_star1 = Image.open(abyss_star1_path) + + for i in range(0,4): + if not os.path.exists(os.path.join(CHAR_DONE_PATH,str(raw_data["reveal_rank"][i]["avatar_id"]) + ".png")): + get_chardone_pic(raw_data["reveal_rank"][i]["avatar_id"],raw_data["reveal_rank"][i]["avatar_icon"],raw_data["reveal_rank"][i]["rarity"]) + char = os.path.join(CHAR_DONE_PATH,str(raw_data["reveal_rank"][i]["avatar_id"]) + ".png") + char_img = Image.open(char) + char_draw = ImageDraw.Draw(char_img) + for k in raw_char_data: + if k['id'] == raw_data["reveal_rank"][i]["avatar_id"]: + char_draw.text((63.5,117),f'{str(raw_data["reveal_rank"][i]["value"])}次',(21,21,21),ys_font(18), anchor="mm") + char_draw.text((95.3,19),f'{str(k["actived_constellation_num"])}','white',ys_font(18)) + if str(k["fetter"]) == "10" or str(k["name"]) == "旅行者": + char_draw.text((93,41.5),"♥",(21,21,21),ys_font(15)) + else: + char_draw.text((95.3,40.5),f'{str(k["fetter"])}',(21,21,21),ys_font(18)) + char_crop = (70 + 123*i,331) + abyss0.paste(char_img,char_crop,char_img) + + for i in range(0,1): + if not os.path.exists(os.path.join(CHAR_DONE_PATH,str(raw_data["damage_rank"][i]["avatar_id"]) + ".png")): + get_chardone_pic(raw_data["damage_rank"][i]["avatar_id"],raw_data["damage_rank"][i]["avatar_icon"],raw_data["reveal_rank"][i]["rarity"]) + char = os.path.join(CHAR_DONE_PATH,str(raw_data["damage_rank"][i]["avatar_id"]) + ".png") + char_img = Image.open(char) + char_draw = ImageDraw.Draw(char_img) + for k in raw_char_data: + if k['id'] == raw_data["damage_rank"][i]["avatar_id"]: + char_draw.text((63.5,117),f'{str(raw_data["damage_rank"][i]["value"])}',(21,21,21),ys_font(18), anchor="mm") + char_draw.text((95.3,19),f'{str(k["actived_constellation_num"])}','white',ys_font(18)) + if str(k["fetter"]) == "10" or str(k["name"]) == "旅行者": + char_draw.text((93,41.5),"♥",(21,21,21),ys_font(15)) + else: + char_draw.text((95.3,40.5),f'{str(k["fetter"])}',(21,21,21),ys_font(18)) + char_crop = (592,331) + abyss0.paste(char_img,char_crop,char_img) + + for i in range(0,3): + if not os.path.exists(os.path.join(CHAR_DONE_PATH,str(raw_data["defeat_rank"][i]["avatar_id"]) + ".png")): + get_chardone_pic(raw_data["defeat_rank"][i]["avatar_id"],raw_data["defeat_rank"][i]["avatar_icon"],raw_data["reveal_rank"][i]["rarity"]) + char = os.path.join(CHAR_DONE_PATH,str(raw_data["defeat_rank"][i]["avatar_id"]) + ".png") + char_img = Image.open(char) + char_draw = ImageDraw.Draw(char_img) + for k in raw_char_data: + if k['id'] == raw_data["defeat_rank"][i]["avatar_id"]: + char_draw.text((63.5,117),f'{str(raw_data["defeat_rank"][i]["value"])}',(21,21,21),ys_font(18), anchor="mm") + char_draw.text((95.3,19),f'{str(k["actived_constellation_num"])}','white',ys_font(18)) + if str(k["fetter"]) == "10" or str(k["name"]) == "旅行者": + char_draw.text((93,41.5),"♥",(21,21,21),ys_font(15)) + else: + char_draw.text((95.3,40.5),f'{str(k["fetter"])}',(21,21,21),ys_font(18)) + char_crop = (70 + 123*i,503) + abyss0.paste(char_img,char_crop,char_img) + + for i in range(0,3): + if not os.path.exists(os.path.join(CHAR_DONE_PATH,str(raw_data["take_damage_rank"][i]["avatar_id"]) + ".png")): + get_chardone_pic(raw_data["take_damage_rank"][i]["avatar_id"],raw_data["take_damage_rank"][i]["avatar_icon"],raw_data["reveal_rank"][i]["rarity"]) + char = os.path.join(CHAR_DONE_PATH,str(raw_data["take_damage_rank"][i]["avatar_id"]) + ".png") + char_img = Image.open(char) + char_draw = ImageDraw.Draw(char_img) + for k in raw_char_data: + if k['id'] == raw_data["take_damage_rank"][i]["avatar_id"]: + char_draw.text((63.5,117),f'{str(raw_data["take_damage_rank"][i]["value"])}',(21,21,21),ys_font(18), anchor="mm") + char_draw.text((95.3,19),f'{str(k["actived_constellation_num"])}','white',ys_font(18)) + if str(k["fetter"]) == "10" or str(k["name"]) == "旅行者": + char_draw.text((93,41.5),"♥",(21,21,21),ys_font(15)) + else: + char_draw.text((95.3,40.5),f'{str(k["fetter"])}',(21,21,21),ys_font(18)) + char_crop = (466 + 123*i,503) + abyss0.paste(char_img,char_crop,char_img) + + for i in range(0,3): + if not os.path.exists(os.path.join(CHAR_DONE_PATH,str(raw_data["normal_skill_rank"][i]["avatar_id"]) + ".png")): + get_chardone_pic(raw_data["normal_skill_rank"][i]["avatar_id"],raw_data["normal_skill_rank"][i]["avatar_icon"],raw_data["reveal_rank"][i]["rarity"]) + char = os.path.join(CHAR_DONE_PATH,str(raw_data["normal_skill_rank"][i]["avatar_id"]) + ".png") + char_img = Image.open(char) + char_draw = ImageDraw.Draw(char_img) + for k in raw_char_data: + if k['id'] == raw_data["normal_skill_rank"][i]["avatar_id"]: + char_draw.text((63.5,117),f'{str(raw_data["normal_skill_rank"][i]["value"])}',(21,21,21),ys_font(18), anchor="mm") + char_draw.text((95.3,19),f'{str(k["actived_constellation_num"])}','white',ys_font(18)) + if str(k["fetter"]) == "10" or str(k["name"]) == "旅行者": + char_draw.text((93,41.5),"♥",(21,21,21),ys_font(15)) + else: + char_draw.text((95.3,40.5),f'{str(k["fetter"])}',(21,21,21),ys_font(18)) + char_crop = (70 + 123*i,676) + abyss0.paste(char_img,char_crop,char_img) + + for i in range(0,3): + if not os.path.exists(os.path.join(CHAR_DONE_PATH,str(raw_data["energy_skill_rank"][i]["avatar_id"]) + ".png")): + get_chardone_pic(raw_data["energy_skill_rank"][i]["avatar_id"],raw_data["energy_skill_rank"][i]["avatar_icon"],raw_data["reveal_rank"][i]["rarity"]) + char = os.path.join(CHAR_DONE_PATH,str(raw_data["energy_skill_rank"][i]["avatar_id"]) + ".png") + char_img = Image.open(char) + char_draw = ImageDraw.Draw(char_img) + for k in raw_char_data: + if k['id'] == raw_data["energy_skill_rank"][i]["avatar_id"]: + char_draw.text((63.5,118),f'{str(raw_data["energy_skill_rank"][i]["value"])}',(21,21,21),ys_font(18), anchor="mm") + char_draw.text((95.3,19),f'{str(k["actived_constellation_num"])}','white',ys_font(18)) + if str(k["fetter"]) == "10" or str(k["name"]) == "旅行者": + char_draw.text((93,41.5),"♥",(21,21,21),ys_font(15)) + else: + char_draw.text((95.3,40.5),f'{str(k["fetter"])}',(21,21,21),ys_font(18)) + char_crop = (466 + 123*i,676) + abyss0.paste(char_img,char_crop,char_img) + + bg_img.paste(abyss0,(0,0),abyss0) + + for j in range(0,len(floors_data["levels"])): + abyss2 = Image.open(abyss2_path) + num_1 = 0 + for i in floors_data['levels'][j]['battles'][0]['avatars']: + if not os.path.exists(os.path.join(CHAR_DONE_PATH,str(i['id']) + ".png")): + get_chardone_pic(i['id'],i['icon'],i['rarity']) + char = os.path.join(CHAR_DONE_PATH,str(i['id']) + ".png") + char_img = Image.open(char) + char_draw = ImageDraw.Draw(char_img) + for k in raw_char_data: + if k['id'] == i['id']: + char_draw.text((40,108),f'Lv.{str(k["level"])}',(21,21,21),ys_font(18)) + char_draw.text((95.3,19),f'{str(k["actived_constellation_num"])}','white',ys_font(18)) + if str(k["fetter"]) == "10" or str(k["name"]) == "旅行者": + char_draw.text((93,41.5),"♥",(21,21,21),ys_font(15)) + else: + char_draw.text((95.3,40.5),f'{str(k["fetter"])}',(21,21,21),ys_font(18)) + char_crop = (70 + 125*(num_1%4),46) + abyss2.paste(char_img,char_crop,char_img) + num_1 = num_1 + 1 + num_2 = 0 + for i in floors_data['levels'][j]['battles'][1]['avatars']: + if not os.path.exists(os.path.join(CHAR_DONE_PATH,str(i['id']) + ".png")): + get_chardone_pic(i['id'],i['icon'],i['rarity']) + char = os.path.join(CHAR_DONE_PATH,str(i['id']) + ".png") + char_img = Image.open(char) + char_draw = ImageDraw.Draw(char_img) + for k in raw_char_data: + if k['id'] == i['id']: + char_draw.text((40,108),f'Lv.{str(k["level"])}',(21,21,21),ys_font(18)) + char_draw.text((95.3,19),f'{str(k["actived_constellation_num"])}','white',ys_font(18)) + if str(k["fetter"]) == "10" or str(k["name"]) == "旅行者": + char_draw.text((93,41.5),"♥",(21,21,21),ys_font(15)) + else: + char_draw.text((95.3,40.5),f'{str(k["fetter"])}',(21,21,21),ys_font(18)) + char_crop = (70 + 125*(num_2%4),180) + abyss2.paste(char_img,char_crop,char_img) + num_2 = num_2 + 1 + star_num = floors_data['levels'][j]['star'] + if star_num == 1: + abyss2.paste(abyss_star1,(640,155),abyss_star1) + abyss2.paste(abyss_star0,(685,155),abyss_star0) + abyss2.paste(abyss_star0,(730,155),abyss_star0) + elif star_num == 0: + abyss2.paste(abyss_star0,(640,155),abyss_star0) + abyss2.paste(abyss_star0,(685,155),abyss_star0) + abyss2.paste(abyss_star0,(730,155),abyss_star0) + elif star_num == 2: + abyss2.paste(abyss_star1,(640,155),abyss_star1) + abyss2.paste(abyss_star1,(685,155),abyss_star1) + abyss2.paste(abyss_star0,(730,155),abyss_star0) + else: + abyss2.paste(abyss_star1,(640,155),abyss_star1) + abyss2.paste(abyss_star1,(685,155),abyss_star1) + abyss2.paste(abyss_star1,(730,155),abyss_star1) + abyss2_text_draw = ImageDraw.Draw(abyss2) + abyss2_text_draw.text((87,30),f"第{j+1}间", (20,20,20), ys_font(21)) + timeStamp1 = int(floors_data['levels'][j]['battles'][0]['timestamp']) + timeStamp2 = int(floors_data['levels'][j]['battles'][1]['timestamp']) + timeArray1 = time.localtime(timeStamp1) + timeArray2 = time.localtime(timeStamp2) + otherStyleTime1 = time.strftime("%Y--%m--%d %H:%M:%S", timeArray1) + otherStyleTime2 = time.strftime("%Y--%m--%d %H:%M:%S", timeArray2) + abyss2_text_draw.text((167,33), f"{otherStyleTime1}/{otherStyleTime2}", (40,40,40), ys_font(19)) + bg_img.paste(abyss2,(0,830+j*315),abyss2) + + bg_img.paste(abyss3,(0,len(floors_data["levels"])*315+840),abyss3) + + text_draw = ImageDraw.Draw(bg_img) + + text_draw.text((250, 85), f"{nickname}", (217,217,217), ys_font(32)) + text_draw.text((260, 125), 'UID ' + f"{uid}", (217,217,217), ys_font(14)) + + text_draw.text((690, 52),raw_data['max_floor'], (65, 65, 65), ys_font(26)) + text_draw.text((690, 97),str(raw_data['total_battle_times']), (65, 65, 65), ys_font(26)) + text_draw.text((690, 142),str(raw_data['total_star']), (65, 65, 65), ys_font(26)) + + bg_img = bg_img.convert('RGB') + result_buffer = BytesIO() + bg_img.save(result_buffer, format='JPEG', subsampling=0, quality=90) + #bg_img.save(result_buffer, format='PNG') + imgmes = 'base64://' + b64encode(result_buffer.getvalue()).decode() + resultmes = f"[CQ:image,file={imgmes}]" + return resultmes + +async def draw_abyss_pic(uid,nickname,floor_num,image = None,mode = 2,date = "1"): + if mode == 3: + mys_data = await GetMysInfo(uid) + mysid_data = mys_data[1] + mys_data = mys_data[0] + uid = mys_data['data']['list'][0]['game_role_id'] + nickname = mys_data['data']['list'][0]['nickname'] + #role_region = mys_data['data']['list'][0]['region'] + role_level = mys_data['data']['list'][0]['level'] + raw_data = await GetSpiralAbyssInfo(uid,"cn_gf01",date,mysid_data) + raw_char_data = await GetInfo(uid,"cn_gf01",date,mysid_data) + else: + raw_data = await GetSpiralAbyssInfo(uid,"cn_gf01",date) + raw_char_data = await GetInfo(uid,"cn_gf01",date) + + if (raw_data["retcode"] != 0): + if (raw_data["retcode"] == 10001): + return ("Cookie错误/过期,请重置Cookie") + elif (raw_data["retcode"] == 10101): + return ("当前cookies已达到30人上限!") + elif (raw_data["retcode"] == 10102): + return ("当前查询id已经设置了隐私,无法查询!") + return ( + "Api报错,返回内容为:\r\n" + + str(raw_data) + "\r\n出现这种情况可能的UID输入错误 or 不存在" + ) + else: + pass + + + is_edit = False + if image != None: + image_file= image.group(1) + image_data = image.group(2) + urllib.request.urlretrieve(f'{image_data}', os.path.join(TEXT_PATH,nickname + '.png')) + is_edit = True + + raw_data = raw_data["data"] + raw_char_data = raw_char_data['data']["avatars"] + floors_data = raw_data['floors'] based_data = [] @@ -103,12 +385,12 @@ async def draw_abyss_pic(uid,nickname,floor_num,image = None,mode = 2): if str(i['index']) == floor_num: based_data = i - floor_star = based_data['star'] - floors1_star = based_data['levels'][0]['star'] - floors2_star = based_data['levels'][1]['star'] - floors3_star = based_data['levels'][2]['star'] - start_time1 = based_data['levels'][0]['battles'][0]['timestamp'] - start_time2 = based_data['levels'][0]['battles'][1]['timestamp'] + #floor_star = based_data['star'] + #floors1_star = based_data['levels'][0]['star'] + #floors2_star = based_data['levels'][1]['star'] + #floors3_star = based_data['levels'][2]['star'] + #start_time1 = based_data['levels'][0]['battles'][0]['timestamp'] + #start_time2 = based_data['levels'][0]['battles'][1]['timestamp'] bg_list = random.choice([x for x in os.listdir(BG_PATH) if os.path.isfile(os.path.join(BG_PATH, x))]) @@ -123,9 +405,9 @@ async def draw_abyss_pic(uid,nickname,floor_num,image = None,mode = 2): levels_num = len(based_data['levels']) - based_w = 800 + based_w = 900 based_h = 240+levels_num*340 - based_scale = math.ceil(based_w/based_h) + based_scale = '%.3f' % (based_w/based_h) if is_edit == True: bg_path_edit = os.path.join(TEXT_PATH,f"{nickname}.png") @@ -134,23 +416,20 @@ async def draw_abyss_pic(uid,nickname,floor_num,image = None,mode = 2): edit_bg = Image.open(bg_path_edit) w, h = edit_bg.size - scale_f = math.ceil(w / h) - new_w = math.ceil(based_w/float(scale_f)) - new_h = math.ceil(based_h*float(scale_f)) - if w > h: - bg_img2 = edit_bg.resize((new_h, based_h),Image.ANTIALIAS) + 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: - if scale_f > based_scale: - bg_img2 = edit_bg.resize((900, new_h),Image.ANTIALIAS) - else: - bg_img2 = edit_bg.resize((900, new_h),Image.ANTIALIAS) + bg_img2 = edit_bg.resize((based_w, new_h),Image.ANTIALIAS) bg_img = bg_img2.crop((0, 0, based_w, based_h)) for i in range(0,len(based_data['levels'])): - x, y = 40, 220 + 340*i - radius = 40 - cropped_img = bg_img.crop((x, y, 760, 518+340*i)) + x, y = 45, 220 + 340*i + radius = 10 + cropped_img = bg_img.crop((x, y, 855, 517+340*i)) blurred_img = cropped_img.filter(ImageFilter.GaussianBlur(5),).convert("RGBA") bg_img.paste(blurred_img, (x, y), create_rounded_rectangle_mask(cropped_img,radius)) @@ -179,7 +458,7 @@ async def draw_abyss_pic(uid,nickname,floor_num,image = None,mode = 2): char_draw.text((93,41.5),"♥",(21,21,21),ys_font(15)) else: char_draw.text((95.3,40.5),f'{str(k["fetter"])}',(21,21,21),ys_font(18)) - char_crop = (41 + 125*(num_1%4),46) + char_crop = (70 + 125*(num_1%4),46) abyss2.paste(char_img,char_crop,char_img) num_1 = num_1 + 1 num_2 = 0 @@ -197,47 +476,47 @@ async def draw_abyss_pic(uid,nickname,floor_num,image = None,mode = 2): char_draw.text((93,41.5),"♥",(21,21,21),ys_font(15)) else: char_draw.text((95.3,40.5),f'{str(k["fetter"])}',(21,21,21),ys_font(18)) - char_crop = (41 + 125*(num_2%4),180) + char_crop = (70 + 125*(num_2%4),180) abyss2.paste(char_img,char_crop,char_img) num_2 = num_2 + 1 star_num = based_data['levels'][j]['star'] if star_num == 1: - abyss2.paste(abyss_star1,(570,155),abyss_star1) - abyss2.paste(abyss_star0,(615,155),abyss_star0) - abyss2.paste(abyss_star0,(660,155),abyss_star0) + abyss2.paste(abyss_star1,(640,155),abyss_star1) + abyss2.paste(abyss_star0,(685,155),abyss_star0) + abyss2.paste(abyss_star0,(730,155),abyss_star0) elif star_num == 0: - abyss2.paste(abyss_star0,(570,155),abyss_star0) - abyss2.paste(abyss_star0,(615,155),abyss_star0) - abyss2.paste(abyss_star0,(660,155),abyss_star0) + abyss2.paste(abyss_star0,(640,155),abyss_star0) + abyss2.paste(abyss_star0,(685,155),abyss_star0) + abyss2.paste(abyss_star0,(730,155),abyss_star0) elif star_num == 2: - abyss2.paste(abyss_star1,(570,155),abyss_star1) - abyss2.paste(abyss_star1,(615,155),abyss_star1) - abyss2.paste(abyss_star0,(660,155),abyss_star0) + abyss2.paste(abyss_star1,(640,155),abyss_star1) + abyss2.paste(abyss_star1,(685,155),abyss_star1) + abyss2.paste(abyss_star0,(730,155),abyss_star0) else: - abyss2.paste(abyss_star1,(570,155),abyss_star1) - abyss2.paste(abyss_star1,(615,155),abyss_star1) - abyss2.paste(abyss_star1,(660,155),abyss_star1) + abyss2.paste(abyss_star1,(640,155),abyss_star1) + abyss2.paste(abyss_star1,(685,155),abyss_star1) + abyss2.paste(abyss_star1,(730,155),abyss_star1) abyss2_text_draw = ImageDraw.Draw(abyss2) - abyss2_text_draw.text((58,30),f"第{j+1}间", (20,20,20), ys_font(21)) + abyss2_text_draw.text((87,30),f"第{j+1}间", (20,20,20), ys_font(21)) timeStamp1 = int(based_data['levels'][j]['battles'][0]['timestamp']) timeStamp2 = int(based_data['levels'][j]['battles'][1]['timestamp']) timeArray1 = time.localtime(timeStamp1) timeArray2 = time.localtime(timeStamp2) otherStyleTime1 = time.strftime("%Y--%m--%d %H:%M:%S", timeArray1) otherStyleTime2 = time.strftime("%Y--%m--%d %H:%M:%S", timeArray2) - abyss2_text_draw.text((138,33), f"{otherStyleTime1}/{otherStyleTime2}", (40,40,40), ys_font(19)) + abyss2_text_draw.text((167,33), f"{otherStyleTime1}/{otherStyleTime2}", (40,40,40), ys_font(19)) bg_img.paste(abyss2,(0,200+j*340),abyss2) bg_img.paste(abyss3,(0,len(based_data['levels'])*340+200),abyss3) text_draw = ImageDraw.Draw(bg_img) - text_draw.text((171.6,89.3), f"{nickname}", (217,217,217), ys_font(32)) - text_draw.text((189.6, 126.3), 'UID ' + f"{uid}", (217,217,217), ys_font(14)) + text_draw.text((210,77), f"{nickname}", (217,217,217), ys_font(32)) + text_draw.text((228, 110), 'UID ' + f"{uid}", (217,217,217), ys_font(14)) if floor_num == "9": - text_draw.text((650, 79), f"{floor_num}", (29,30,63), ys_font(50)) + text_draw.text((687, 67), f"{floor_num}", (29,30,63), ys_font(50)) else: - text_draw.text((630, 79), f"{floor_num}", (29,30,63), ys_font(50)) + text_draw.text((670, 67), f"{floor_num}", (29,30,63), ys_font(50)) bg_img = bg_img.convert('RGB') result_buffer = BytesIO() @@ -248,25 +527,17 @@ async def draw_abyss_pic(uid,nickname,floor_num,image = None,mode = 2): return resultmes async def draw_pic(uid,nickname,image = None,mode = 2,role_level = None): - is_edit = False - if image: - image_file= image.group(1) - image_data = image.group(2) - urllib.request.urlretrieve(f'{image_data}', os.path.join(TEXT_PATH,nickname + '.png')) - is_edit = True - if mode == 3: mys_data = await GetMysInfo(uid) mysid_data = mys_data[1] mys_data = mys_data[0] uid = mys_data['data']['list'][0]['game_role_id'] nickname = mys_data['data']['list'][0]['nickname'] - #role_region = mys_data['data']['list'][0]['region'] role_level = mys_data['data']['list'][0]['level'] raw_data = await GetInfo(uid,"cn_gf01","1",mysid_data) else: raw_data = await GetInfo(uid) - + if (raw_data["retcode"] != 0): if (raw_data["retcode"] == 10001): return ("Cookie错误/过期,请重置Cookie") @@ -320,9 +591,16 @@ async def draw_pic(uid,nickname,image = None,mode = 2,role_level = None): char_lie = char_num%6 based_w = 900 - based_h = 840+char_hang*130 + based_h = 890+char_hang*130 based_scale = '%.3f' % (based_w/based_h) + is_edit = False + if image: + image_file= image.group(1) + image_data = image.group(2) + urllib.request.urlretrieve(f'{image_data}', os.path.join(TEXT_PATH,nickname + '.png')) + is_edit = True + if is_edit == True: bg_path_edit = os.path.join(TEXT_PATH,f"{nickname}.png") else: @@ -352,8 +630,8 @@ async def draw_pic(uid,nickname,image = None,mode = 2,role_level = None): bg_img.paste(panle1,(0,0),panle1) for i in range(0,char_hang): - bg_img.paste(panle2,(0,750+i*130),panle2) - bg_img.paste(panle3,(0,char_hang*130+750),panle3) + bg_img.paste(panle2,(0,800+i*130),panle2) + bg_img.paste(panle3,(0,char_hang*130+800),panle3) text_draw = ImageDraw.Draw(bg_img) @@ -367,42 +645,47 @@ async def draw_pic(uid,nickname,image = None,mode = 2,role_level = None): text_draw.text((640, 139.3),str(raw_data['stats']['achievement_number']), (65, 65, 65), ys_font(26)) text_draw.text((640, 183.9),raw_data['stats']['spiral_abyss'], (65, 65, 65), ys_font(26)) - text_draw.text((241, 390),str(raw_data['stats']['common_chest_number']),(65, 65, 65), ys_font(26)) - text_draw.text((241, 432),str(raw_data['stats']['exquisite_chest_number']),(65, 65, 65), ys_font(26)) - text_draw.text((241, 474),str(raw_data['stats']['precious_chest_number']), (65, 65, 65), ys_font(26)) - text_draw.text((241, 516),str(raw_data['stats']['luxurious_chest_number']), (65, 65, 65), ys_font(26)) + text_draw.text((258, 382.4),str(raw_data['stats']['magic_chest_number']), (65, 65, 65), ys_font(24)) + text_draw.text((258, 442),str(raw_data['stats']['common_chest_number']),(65, 65, 65), ys_font(24)) + text_draw.text((258, 501.6),str(raw_data['stats']['exquisite_chest_number']),(65, 65, 65), ys_font(24)) + text_draw.text((258, 561.2),str(raw_data['stats']['precious_chest_number']), (65, 65, 65), ys_font(24)) + text_draw.text((258, 620.8),str(raw_data['stats']['luxurious_chest_number']), (65, 65, 65), ys_font(24)) - text_draw.text((241, 558),str(raw_data['stats']['avatar_number']),(65, 65, 65), ys_font(26)) - text_draw.text((241, 600),str(raw_data['stats']['way_point_number']),(65, 65, 65), ys_font(26)) - text_draw.text((241, 642),str(raw_data['stats']['domain_number']),(65, 65, 65), ys_font(26)) + text_draw.text((258, 680.4),str(raw_data['stats']['avatar_number']),(65, 65, 65), ys_font(24)) + + text_draw.text((745, 474.5),str(raw_data['stats']['way_point_number']),(65, 65, 65), ys_font(24)) + text_draw.text((745, 514),str(raw_data['stats']['domain_number']),(65, 65, 65), ys_font(24)) #蒙德 - text_draw.text((480, 380),str(raw_data['world_explorations'][3]['exploration_percentage']/10) + '%',(65, 65, 65), ys_font(23)) - text_draw.text((480, 410),'lv.' + str(raw_data['world_explorations'][3]['level']),(65, 65, 65), ys_font(23)) - text_draw.text((505, 440), str(raw_data['stats']['anemoculus_number']), (65, 65, 65), ys_font(23)) + text_draw.text((490, 370),str(raw_data['world_explorations'][3]['exploration_percentage']/10) + '%',(65, 65, 65), ys_font(22)) + text_draw.text((490, 400),'lv.' + str(raw_data['world_explorations'][3]['level']),(65, 65, 65), ys_font(22)) + text_draw.text((513, 430), str(raw_data['stats']['anemoculus_number']), (65, 65, 65), ys_font(22)) #璃月 - text_draw.text((715, 380),str(raw_data['world_explorations'][2]['exploration_percentage']/10) + '%',(65, 65, 65), ys_font(23)) - text_draw.text((715, 410),'lv.' + str(raw_data['world_explorations'][2]['level']),(65, 65, 65), ys_font(23)) - text_draw.text((740, 440), str(raw_data['stats']['geoculus_number']), (65, 65, 65), ys_font(23)) + text_draw.text((490, 490),str(raw_data['world_explorations'][2]['exploration_percentage']/10) + '%',(65, 65, 65), ys_font(22)) + text_draw.text((490, 520),'lv.' + str(raw_data['world_explorations'][2]['level']),(65, 65, 65), ys_font(22)) + text_draw.text((513, 550), str(raw_data['stats']['geoculus_number']), (65, 65, 65), ys_font(22)) #雪山 - text_draw.text((480, 522),str(raw_data['world_explorations'][1]['exploration_percentage']/10) + '%',(65, 65, 65), ys_font(23)) - text_draw.text((480, 556),'lv.' + str(raw_data['world_explorations'][1]['level']),(65, 65, 65), ys_font(23)) + text_draw.text((745, 379.5),str(raw_data['world_explorations'][1]['exploration_percentage']/10) + '%',(65, 65, 65), ys_font(22)) + text_draw.text((745, 413.1),'lv.' + str(raw_data['world_explorations'][1]['level']),(65, 65, 65), ys_font(22)) #稻妻 - text_draw.text((715, 497),str(raw_data['world_explorations'][0]['exploration_percentage']/10) + '%',(65, 65, 65), ys_font(23)) - text_draw.text((715, 525),'lv.' + str(raw_data['world_explorations'][0]['level']),(65, 65, 65), ys_font(23)) - text_draw.text((715, 553),'lv.' + str(raw_data['world_explorations'][0]['offerings'][0]['level']),(65, 65, 65), ys_font(23)) - text_draw.text((740, 581), str(raw_data['stats']['electroculus_number']), (65, 65, 65), ys_font(23)) + text_draw.text((490, 608),str(raw_data['world_explorations'][0]['exploration_percentage']/10) + '%',(65, 65, 65), ys_font(22)) + text_draw.text((490, 635),'lv.' + str(raw_data['world_explorations'][0]['level']),(65, 65, 65), ys_font(22)) + text_draw.text((490, 662),'lv.' + str(raw_data['world_explorations'][0]['offerings'][0]['level']),(65, 65, 65), ys_font(22)) + text_draw.text((513, 689), str(raw_data['stats']['electroculus_number']), (65, 65, 65), ys_font(22)) if len(raw_data['homes']): - text_draw.text((480, 622),'lv.' + str(raw_data['homes'][0]['level']),(65, 65, 65), ys_font(24)) - text_draw.text((480, 653),str(raw_data['homes'][0]['visit_num']),(65, 65, 65), ys_font(24)) - text_draw.text((715, 622),str(raw_data['homes'][0]['item_num']),(65, 65, 65), ys_font(24)) - text_draw.text((715, 653),str(raw_data['homes'][0]['comfort_num']),(65, 65, 65), ys_font(24)) + text_draw.text((693, 572.4),'lv.' + str(raw_data['homes'][0]['level']),(65, 65, 65), ys_font(22)) + text_draw.text((693, 610.4),str(raw_data['homes'][0]['visit_num']),(65, 65, 65), ys_font(22)) + text_draw.text((693, 648.4),str(raw_data['homes'][0]['item_num']),(65, 65, 65), ys_font(22)) + text_draw.text((693, 686.4),str(raw_data['homes'][0]['comfort_num']),(65, 65, 65), ys_font(22)) else: - text_draw.text((650, 640),'未开',(0, 0, 0), ys_font(26)) + text_draw.text((693, 572.4),"未开",(65, 65, 65), ys_font(22)) + text_draw.text((693, 610.4),"未开",(65, 65, 65), ys_font(22)) + text_draw.text((693, 648.4),"未开",(65, 65, 65), ys_font(22)) + text_draw.text((693, 686.4),"未开",(65, 65, 65), ys_font(22)) if mode == 1: char_data.sort(key=lambda x: (-x['rarity'],-x['level'],-x['fetter'])) @@ -420,7 +703,7 @@ async def draw_pic(uid,nickname,image = None,mode = 2,role_level = None): else: char_draw.text((95.3,40.5),f'{str(char_data[num]["fetter"])}',(21,21,21),ys_font(18)) - char_crop = (68+129*(num%6),750+130*(num//6)) + char_crop = (68+129*(num%6),800+130*(num//6)) bg_img.paste(char_img,char_crop,char_img) num = num+1 else: @@ -542,7 +825,7 @@ async def draw_pic(uid,nickname,image = None,mode = 2,role_level = None): else: char_draw.text((100,41),f'{str(char_fetter)}',(21,21,21),ys_font(16)) - char_crop = (68+129*(num%6),750+130*(num//6)) + char_crop = (68+129*(num%6),800+130*(num//6)) bg_img.paste(charpic,char_crop,charpic) num = num+1 diff --git a/mys/bg/1.jpg b/mys/bg/1.jpg new file mode 100644 index 00000000..05d8ba1e Binary files /dev/null and b/mys/bg/1.jpg differ diff --git a/mys/bg/2.jpg b/mys/bg/2.jpg new file mode 100644 index 00000000..1007c78c Binary files /dev/null and b/mys/bg/2.jpg differ diff --git a/mys/bg/2.png b/mys/bg/2.png deleted file mode 100644 index ffc63fa9..00000000 Binary files a/mys/bg/2.png and /dev/null differ diff --git a/mys/texture2d/abyss_0.png b/mys/texture2d/abyss_0.png new file mode 100644 index 00000000..7182b035 Binary files /dev/null and b/mys/texture2d/abyss_0.png differ diff --git a/mys/texture2d/abyss_1.png b/mys/texture2d/abyss_1.png index 9aa288a1..ebc11d75 100644 Binary files a/mys/texture2d/abyss_1.png and b/mys/texture2d/abyss_1.png differ diff --git a/mys/texture2d/abyss_2.png b/mys/texture2d/abyss_2.png index 26182719..ba061df2 100644 Binary files a/mys/texture2d/abyss_2.png and b/mys/texture2d/abyss_2.png differ diff --git a/mys/texture2d/abyss_3.png b/mys/texture2d/abyss_3.png index b34fb5b1..0fba2dbc 100644 Binary files a/mys/texture2d/abyss_3.png and b/mys/texture2d/abyss_3.png differ diff --git a/mys/texture2d/mys_1.png b/mys/texture2d/mys_1.png index ab59690c..3fcdbfbb 100644 Binary files a/mys/texture2d/mys_1.png and b/mys/texture2d/mys_1.png differ diff --git a/mys/texture2d/panle_1.png b/mys/texture2d/panle_1.png index 5f32dea8..aff225e7 100644 Binary files a/mys/texture2d/panle_1.png and b/mys/texture2d/panle_1.png differ diff --git a/readme/1.PNG b/readme/1.PNG index 63547d86..c3c8beb4 100644 Binary files a/readme/1.PNG and b/readme/1.PNG differ diff --git a/readme/10.png b/readme/10.png deleted file mode 100644 index c89b8ccd..00000000 Binary files a/readme/10.png and /dev/null differ diff --git a/readme/11.png b/readme/11.png deleted file mode 100644 index 752eefd2..00000000 Binary files a/readme/11.png and /dev/null differ diff --git a/readme/12.png b/readme/12.png deleted file mode 100644 index 48edebc0..00000000 Binary files a/readme/12.png and /dev/null differ diff --git a/readme/13.png b/readme/13.png deleted file mode 100644 index f43a7bbe..00000000 Binary files a/readme/13.png and /dev/null differ diff --git a/readme/14.png b/readme/14.png deleted file mode 100644 index 42eb1e59..00000000 Binary files a/readme/14.png and /dev/null differ diff --git a/readme/2.png b/readme/2.png index 51ca9183..4e5490ea 100644 Binary files a/readme/2.png and b/readme/2.png differ diff --git a/readme/3.png b/readme/3.png index ccb12eb4..fb0f9aff 100644 Binary files a/readme/3.png and b/readme/3.png differ diff --git a/readme/4.png b/readme/4.png deleted file mode 100644 index 66ccb7f7..00000000 Binary files a/readme/4.png and /dev/null differ diff --git a/readme/5.PNG b/readme/5.PNG deleted file mode 100644 index 364c3c6b..00000000 Binary files a/readme/5.PNG and /dev/null differ diff --git a/readme/6.PNG b/readme/6.PNG deleted file mode 100644 index 8ffcfd63..00000000 Binary files a/readme/6.PNG and /dev/null differ diff --git a/readme/7.PNG b/readme/7.PNG deleted file mode 100644 index 36ec385a..00000000 Binary files a/readme/7.PNG and /dev/null differ diff --git a/readme/8.PNG b/readme/8.PNG deleted file mode 100644 index c2260391..00000000 Binary files a/readme/8.PNG and /dev/null differ diff --git a/readme/9.PNG b/readme/9.PNG deleted file mode 100644 index 1c7e1f36..00000000 Binary files a/readme/9.PNG and /dev/null differ