✨ 0.4.0 支持怎么养、给谁用 & 更新周本图片 & 支持深渊
This commit is contained in:
parent
6c677d1d8e
commit
a395db7b50
BIN
assets/Genshin_All_Char.xlsx
Normal file
BIN
assets/Genshin_All_Char.xlsx
Normal file
Binary file not shown.
52
assets/data/id2name.json
Normal file
52
assets/data/id2name.json
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
{
|
||||||
|
"10000002": "神里绫华",
|
||||||
|
"10000003": "琴",
|
||||||
|
"10000006": "丽莎",
|
||||||
|
"10000005": "空",
|
||||||
|
"10000007": "荧",
|
||||||
|
"10000014": "芭芭拉",
|
||||||
|
"10000015": "凯亚",
|
||||||
|
"10000016": "迪卢克",
|
||||||
|
"10000020": "雷泽",
|
||||||
|
"10000021": "安柏",
|
||||||
|
"10000022": "温迪",
|
||||||
|
"10000023": "香菱",
|
||||||
|
"10000024": "北斗",
|
||||||
|
"10000025": "行秋",
|
||||||
|
"10000026": "魈",
|
||||||
|
"10000027": "凝光",
|
||||||
|
"10000029": "可莉",
|
||||||
|
"10000030": "钟离",
|
||||||
|
"10000031": "菲谢尔",
|
||||||
|
"10000032": "班尼特",
|
||||||
|
"10000033": "达达利亚",
|
||||||
|
"10000034": "诺艾尔",
|
||||||
|
"10000035": "七七",
|
||||||
|
"10000036": "重云",
|
||||||
|
"10000037": "甘雨",
|
||||||
|
"10000038": "阿贝多",
|
||||||
|
"10000039": "迪奥娜",
|
||||||
|
"10000041": "莫娜",
|
||||||
|
"10000042": "刻晴",
|
||||||
|
"10000043": "砂糖",
|
||||||
|
"10000044": "辛焱",
|
||||||
|
"10000045": "罗莎莉亚",
|
||||||
|
"10000046": "胡桃",
|
||||||
|
"10000047": "枫原万叶",
|
||||||
|
"10000048": "烟绯",
|
||||||
|
"10000049": "宵宫",
|
||||||
|
"10000050": "托马",
|
||||||
|
"10000051": "优菈",
|
||||||
|
"10000052": "雷电将军",
|
||||||
|
"10000053": "早柚",
|
||||||
|
"10000054": "珊瑚宫心海",
|
||||||
|
"10000055": "五郎",
|
||||||
|
"10000056": "九条裟罗",
|
||||||
|
"10000057": "荒泷一斗",
|
||||||
|
"10000058": "八重神子",
|
||||||
|
"10000062": "埃洛伊",
|
||||||
|
"10000063": "申鹤",
|
||||||
|
"10000064": "云堇",
|
||||||
|
"10000066": "神里绫人",
|
||||||
|
"注释1": "10000005/7分别对应哥哥和妹妹"
|
||||||
|
}
|
Binary file not shown.
Before Width: | Height: | Size: 3.0 MiB After Width: | Height: | Size: 7.4 MiB |
91
defs/char_adv.py
Normal file
91
defs/char_adv.py
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
import os
|
||||||
|
|
||||||
|
from openpyxl import load_workbook
|
||||||
|
|
||||||
|
FILE_PATH = "assets"
|
||||||
|
char_adv_im = '''【{}】
|
||||||
|
【五星武器】:{}
|
||||||
|
【四星武器】:{}
|
||||||
|
【三星武器】:{}
|
||||||
|
【圣遗物】:
|
||||||
|
{}'''
|
||||||
|
|
||||||
|
|
||||||
|
async def weapon_adv(name):
|
||||||
|
char_adv_path = os.path.join(FILE_PATH, "Genshin_All_Char.xlsx")
|
||||||
|
wb = load_workbook(char_adv_path)
|
||||||
|
ws = wb.active
|
||||||
|
|
||||||
|
weapon_name = ""
|
||||||
|
char_list = []
|
||||||
|
for c in range(2, 5):
|
||||||
|
for r in range(2, 300):
|
||||||
|
if ws.cell(r, c).value:
|
||||||
|
# if all(i in ws.cell(r,c).value for i in name):
|
||||||
|
if name in ws.cell(r, c).value:
|
||||||
|
weapon_name = ws.cell(r, c).value
|
||||||
|
char_list.append(ws.cell(2 + ((r - 2) // 5) * 5, 1).value)
|
||||||
|
|
||||||
|
if char_list:
|
||||||
|
im = ','.join(char_list)
|
||||||
|
im = im + " 可能会用到【{}】".format(weapon_name)
|
||||||
|
else:
|
||||||
|
im = " 没有角色能使用【{}】".format(weapon_name)
|
||||||
|
return im
|
||||||
|
|
||||||
|
|
||||||
|
async def char_adv(name):
|
||||||
|
char_adv_path = os.path.join(FILE_PATH, "Genshin_All_Char.xlsx")
|
||||||
|
wb = load_workbook(char_adv_path)
|
||||||
|
ws = wb.active
|
||||||
|
char_list = ws["A"]
|
||||||
|
index = None
|
||||||
|
for i in char_list:
|
||||||
|
if i.value:
|
||||||
|
if all(g in i.value for g in name):
|
||||||
|
# if name in i.value:
|
||||||
|
index = i.row
|
||||||
|
char_name = i.value
|
||||||
|
if index:
|
||||||
|
weapon_5star = ""
|
||||||
|
for i in range(index, index + 5):
|
||||||
|
if ws.cell(i, 2).value:
|
||||||
|
weapon_5star += ws.cell(i, 2).value + ">"
|
||||||
|
if weapon_5star != "":
|
||||||
|
weapon_5star = weapon_5star[:-1]
|
||||||
|
else:
|
||||||
|
weapon_5star = "无推荐"
|
||||||
|
|
||||||
|
weapon_4star = ""
|
||||||
|
for i in range(index, index + 5):
|
||||||
|
if ws.cell(i, 3).value:
|
||||||
|
weapon_4star += ws.cell(i, 3).value + ">"
|
||||||
|
if weapon_4star != "":
|
||||||
|
weapon_4star = weapon_4star[:-1]
|
||||||
|
else:
|
||||||
|
weapon_4star = "无推荐"
|
||||||
|
|
||||||
|
weapon_3star = ""
|
||||||
|
for i in range(index, index + 5):
|
||||||
|
if ws.cell(i, 4).value:
|
||||||
|
weapon_3star += ws.cell(i, 4).value + ">"
|
||||||
|
if weapon_3star != "":
|
||||||
|
weapon_3star = weapon_3star[:-1]
|
||||||
|
else:
|
||||||
|
weapon_3star = "无推荐"
|
||||||
|
|
||||||
|
artifacts = ""
|
||||||
|
for i in range(index, index + 5):
|
||||||
|
if ws.cell(i, 5).value:
|
||||||
|
if ws.cell(i, 6).value:
|
||||||
|
artifacts += ws.cell(i, 5).value + "*2" + ws.cell(i, 6).value + "*2" + "\n"
|
||||||
|
else:
|
||||||
|
artifacts += ws.cell(i, 5).value + "*4" + "\n"
|
||||||
|
|
||||||
|
if artifacts != "":
|
||||||
|
artifacts = artifacts[:-1]
|
||||||
|
else:
|
||||||
|
artifacts = "无推荐"
|
||||||
|
|
||||||
|
im = char_adv_im.format(char_name, weapon_5star, weapon_4star, weapon_3star, artifacts) # noqa
|
||||||
|
return im
|
108
defs/db.py
108
defs/db.py
@ -9,12 +9,19 @@ import traceback
|
|||||||
from shutil import copyfile
|
from shutil import copyfile
|
||||||
|
|
||||||
import requests
|
import requests
|
||||||
|
from httpx import AsyncClient
|
||||||
|
|
||||||
from ci import client
|
from ci import client
|
||||||
from defs.mysbbs import MihoyoBbs
|
from defs.mysbbs import MihoyoBbs
|
||||||
|
|
||||||
mhyVersion = "2.11.1"
|
mhyVersion = "2.11.1"
|
||||||
|
|
||||||
|
|
||||||
|
def regex_func(value, patter):
|
||||||
|
c_pattern = re.compile(r"account_id={}".format(patter))
|
||||||
|
return c_pattern.search(value) is not None
|
||||||
|
|
||||||
|
|
||||||
async def cookiesDB(uid, Cookies, qid):
|
async def cookiesDB(uid, Cookies, qid):
|
||||||
conn = sqlite3.connect('ID_DATA.db')
|
conn = sqlite3.connect('ID_DATA.db')
|
||||||
c = conn.cursor()
|
c = conn.cursor()
|
||||||
@ -406,29 +413,28 @@ def functionRegex(value, patter):
|
|||||||
|
|
||||||
|
|
||||||
def cacheDB(uid, mode=1, mys=None):
|
def cacheDB(uid, mode=1, mys=None):
|
||||||
use = ''
|
|
||||||
conn = sqlite3.connect('ID_DATA.db')
|
conn = sqlite3.connect('ID_DATA.db')
|
||||||
c = conn.cursor()
|
c = conn.cursor()
|
||||||
c.execute('''CREATE TABLE IF NOT EXISTS CookiesCache
|
c.execute('''CREATE TABLE IF NOT EXISTS CookiesCache
|
||||||
(UID TEXT PRIMARY KEY,
|
(UID TEXT PRIMARY KEY,
|
||||||
MYSID TEXT,
|
MYSID TEXT,
|
||||||
Cookies TEXT);''')
|
Cookies TEXT);''')
|
||||||
if mode == 2:
|
|
||||||
cursor = c.execute("SELECT * FROM CookiesCache WHERE MYSID = ?", (uid,))
|
if mode == 1:
|
||||||
c_data = cursor.fetchall()
|
|
||||||
else:
|
|
||||||
if mys:
|
if mys:
|
||||||
cursor = c.execute("SELECT * FROM CookiesCache WHERE MYSID = ?", (mys,))
|
cursor = c.execute("SELECT * FROM CookiesCache WHERE MYSID = ?", (mys,))
|
||||||
c_data = cursor.fetchall()
|
|
||||||
else:
|
else:
|
||||||
cursor = c.execute("SELECT * FROM CookiesCache WHERE UID = ?", (uid,))
|
cursor = c.execute("SELECT * FROM CookiesCache WHERE UID = ?", (uid,))
|
||||||
c_data = cursor.fetchall()
|
else:
|
||||||
|
cursor = c.execute("SELECT * FROM CookiesCache WHERE MYSID = ?", (uid,))
|
||||||
|
c_data = cursor.fetchall()
|
||||||
|
|
||||||
if len(c_data) == 0:
|
if len(c_data) == 0:
|
||||||
if mode == 2:
|
if mode == 2:
|
||||||
conn.create_function("REGEXP", 2, functionRegex)
|
conn.create_function("REGEXP", 2, regex_func)
|
||||||
cursor = c.execute("SELECT * FROM NewCookiesTable WHERE REGEXP(Cookies, ?)", (uid,))
|
cursor = c.execute("SELECT * FROM NewCookiesTable WHERE REGEXP(Cookies, ?)", (uid,))
|
||||||
d_data = cursor.fetchall()
|
d_data = cursor.fetchall()
|
||||||
|
|
||||||
else:
|
else:
|
||||||
cursor = c.execute("SELECT * FROM NewCookiesTable WHERE UID = ?", (uid,))
|
cursor = c.execute("SELECT * FROM NewCookiesTable WHERE UID = ?", (uid,))
|
||||||
d_data = cursor.fetchall()
|
d_data = cursor.fetchall()
|
||||||
@ -438,33 +444,33 @@ def cacheDB(uid, mode=1, mys=None):
|
|||||||
use = d_data[0][1]
|
use = d_data[0][1]
|
||||||
if mode == 1:
|
if mode == 1:
|
||||||
c.execute("INSERT OR IGNORE INTO CookiesCache (Cookies,UID) \
|
c.execute("INSERT OR IGNORE INTO CookiesCache (Cookies,UID) \
|
||||||
VALUES (?, ?)", (use, uid))
|
VALUES (?, ?)", (use, uid))
|
||||||
elif mode == 2:
|
elif mode == 2:
|
||||||
c.execute("INSERT OR IGNORE INTO CookiesCache (Cookies,MYSID) \
|
c.execute("INSERT OR IGNORE INTO CookiesCache (Cookies,MYSID) \
|
||||||
VALUES (?, ?)", (use, uid))
|
VALUES (?, ?)", (use, uid))
|
||||||
else:
|
else:
|
||||||
cookiesrow = c.execute("SELECT * FROM NewCookiesTable WHERE Extra IS NULL ORDER BY RANDOM() LIMIT 1")
|
cookies_row = c.execute("SELECT * FROM NewCookiesTable WHERE Extra IS NULL ORDER BY RANDOM() LIMIT 1")
|
||||||
e_data = cookiesrow.fetchall()
|
e_data = cookies_row.fetchall()
|
||||||
if len(e_data) != 0:
|
if len(e_data) != 0:
|
||||||
if mode == 1:
|
if mode == 1:
|
||||||
c.execute("INSERT OR IGNORE INTO CookiesCache (Cookies,UID) \
|
c.execute("INSERT OR IGNORE INTO CookiesCache (Cookies,UID) \
|
||||||
VALUES (?, ?)", (e_data[0][1], uid))
|
VALUES (?, ?)", (e_data[0][1], uid))
|
||||||
elif mode == 2:
|
elif mode == 2:
|
||||||
c.execute("INSERT OR IGNORE INTO CookiesCache (Cookies,MYSID) \
|
c.execute("INSERT OR IGNORE INTO CookiesCache (Cookies,MYSID) \
|
||||||
VALUES (?, ?)", (e_data[0][1], uid))
|
VALUES (?, ?)", (e_data[0][1], uid))
|
||||||
use = e_data[0][1]
|
use = e_data[0][1]
|
||||||
else:
|
else:
|
||||||
return "没有可以使用的Cookies!"
|
return "没有可以使用的Cookies!"
|
||||||
else:
|
else:
|
||||||
cookiesrow = c.execute("SELECT * FROM NewCookiesTable WHERE Extra IS NULL ORDER BY RANDOM() LIMIT 1")
|
cookies_row = c.execute("SELECT * FROM NewCookiesTable WHERE Extra IS NULL ORDER BY RANDOM() LIMIT 1")
|
||||||
e_data = cookiesrow.fetchall()
|
e_data = cookies_row.fetchall()
|
||||||
if len(e_data) != 0:
|
if len(e_data) != 0:
|
||||||
if mode == 1:
|
if mode == 1:
|
||||||
c.execute("INSERT OR IGNORE INTO CookiesCache (Cookies,UID) \
|
c.execute("INSERT OR IGNORE INTO CookiesCache (Cookies,UID) \
|
||||||
VALUES (?, ?)", (e_data[0][1], uid))
|
VALUES (?, ?)", (e_data[0][1], uid))
|
||||||
elif mode == 2:
|
elif mode == 2:
|
||||||
c.execute("INSERT OR IGNORE INTO CookiesCache (Cookies,MYSID) \
|
c.execute("INSERT OR IGNORE INTO CookiesCache (Cookies,MYSID) \
|
||||||
VALUES (?, ?)", (e_data[0][1], uid))
|
VALUES (?, ?)", (e_data[0][1], uid))
|
||||||
use = e_data[0][1]
|
use = e_data[0][1]
|
||||||
else:
|
else:
|
||||||
return "没有可以使用的Cookies!"
|
return "没有可以使用的Cookies!"
|
||||||
@ -608,3 +614,63 @@ async def GetInfo(Uid, ck, ServerID="cn_gf01"):
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
print("米游社基础信息读取老Api失败!")
|
print("米游社基础信息读取老Api失败!")
|
||||||
print(e.with_traceback)
|
print(e.with_traceback)
|
||||||
|
|
||||||
|
|
||||||
|
async def get_spiral_abyss_info(uid, ck, schedule_type="1", server_id="cn_gf01"):
|
||||||
|
if uid[0] == '5':
|
||||||
|
server_id = "cn_qd01"
|
||||||
|
try:
|
||||||
|
async with AsyncClient() as c:
|
||||||
|
req = await c.get(
|
||||||
|
url="https://api-takumi.mihoyo.com/game_record/app/genshin/api/spiralAbyss",
|
||||||
|
headers={
|
||||||
|
'DS': DSGet("role_id=" + uid + "&schedule_type=" + schedule_type + "&server=" + server_id),
|
||||||
|
'Origin': 'https://webstatic.mihoyo.com',
|
||||||
|
'Cookie': ck,
|
||||||
|
'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/'
|
||||||
|
},
|
||||||
|
params={
|
||||||
|
"schedule_type": schedule_type,
|
||||||
|
"role_id": uid,
|
||||||
|
"server": server_id
|
||||||
|
}
|
||||||
|
)
|
||||||
|
data = json.loads(req.text)
|
||||||
|
return data
|
||||||
|
except requests.exceptions.SSLError:
|
||||||
|
try:
|
||||||
|
async with AsyncClient() as c:
|
||||||
|
req = await c.get(
|
||||||
|
url="https://api-takumi-record.mihoyo.com/game_record/app/genshin/api/spiralAbyss",
|
||||||
|
headers={
|
||||||
|
'DS': DSGet(
|
||||||
|
"role_id=" + uid + "&schedule_type=" + schedule_type + "&server=" + server_id),
|
||||||
|
'Origin': 'https://webstatic.mihoyo.com',
|
||||||
|
'Cookie': ck,
|
||||||
|
'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/'
|
||||||
|
},
|
||||||
|
params={
|
||||||
|
"role_id": uid,
|
||||||
|
"server": server_id,
|
||||||
|
"bbs_presentation_style": "fullscreen",
|
||||||
|
"bbs_auth_required": "true",
|
||||||
|
"utm_source": "bbs",
|
||||||
|
"utm_medium": "mys",
|
||||||
|
"utm_campaign": "icon"
|
||||||
|
}
|
||||||
|
)
|
||||||
|
data = json.loads(req.text)
|
||||||
|
return data
|
||||||
|
except json.decoder.JSONDecodeError:
|
||||||
|
print("深渊信息读取新Api失败!")
|
||||||
|
except Exception as e:
|
||||||
|
print("深渊信息读取老Api失败!")
|
||||||
|
print(e.with_traceback)
|
||||||
|
587
defs/spiral_abyss.py
Normal file
587
defs/spiral_abyss.py
Normal file
@ -0,0 +1,587 @@
|
|||||||
|
import math
|
||||||
|
import os
|
||||||
|
import random
|
||||||
|
import time
|
||||||
|
from io import BytesIO
|
||||||
|
from httpx import get
|
||||||
|
from PIL import Image, ImageDraw, ImageFont
|
||||||
|
|
||||||
|
from defs.db import cacheDB, GetMysInfo, GetInfo, errorDB, get_spiral_abyss_info
|
||||||
|
|
||||||
|
FILE2_PATH = os.path.join("assets")
|
||||||
|
CHAR_DONE_PATH = os.path.join(FILE2_PATH, "char_done")
|
||||||
|
TEXT_PATH = os.path.join(FILE2_PATH, "bg2")
|
||||||
|
BG_PATH = os.path.join(FILE2_PATH, "bg")
|
||||||
|
|
||||||
|
|
||||||
|
def get_char_done_pic(_id, url, star):
|
||||||
|
char_data = get(url).content
|
||||||
|
if star == 4:
|
||||||
|
star1_path = os.path.join(TEXT_PATH, '4star_1.png')
|
||||||
|
star2_path = os.path.join(TEXT_PATH, '4star_2.png')
|
||||||
|
else:
|
||||||
|
star1_path = os.path.join(TEXT_PATH, '5star_1.png')
|
||||||
|
star2_path = os.path.join(TEXT_PATH, '5star_2.png')
|
||||||
|
star_1 = Image.open(star1_path)
|
||||||
|
star_2 = Image.open(star2_path)
|
||||||
|
char_img = Image.open(BytesIO(char_data)).resize((104, 104), Image.ANTIALIAS)
|
||||||
|
star_1.paste(char_img, (12, 15), char_img)
|
||||||
|
star_1.paste(star_2, (0, 0), star_2)
|
||||||
|
star_1.save(os.path.join(CHAR_DONE_PATH, str(_id) + '.png'))
|
||||||
|
|
||||||
|
|
||||||
|
def genshin_font(size):
|
||||||
|
return ImageFont.truetype(f"assets{os.sep}fonts{os.sep}yuan_shen.ttf", size=size, encoding="utf-8")
|
||||||
|
|
||||||
|
|
||||||
|
async def draw_abyss0_pic(uid, nickname, image=None, mode=2, date="1"):
|
||||||
|
# 获取Cookies
|
||||||
|
while True:
|
||||||
|
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)
|
||||||
|
for i in mys_data['data']['list']:
|
||||||
|
if i['game_id'] != 2:
|
||||||
|
mys_data['data']['list'].remove(i)
|
||||||
|
uid = mys_data['data']['list'][0]['game_role_id']
|
||||||
|
nickname = mys_data['data']['list'][0]['nickname']
|
||||||
|
|
||||||
|
raw_data = await get_spiral_abyss_info(uid, use_cookies, date)
|
||||||
|
raw_char_data = await GetInfo(uid, use_cookies)
|
||||||
|
|
||||||
|
if raw_data["retcode"] != 0:
|
||||||
|
if raw_data["retcode"] == 10001:
|
||||||
|
# return ("Cookie错误/过期,请重置Cookie")
|
||||||
|
errorDB(use_cookies, "error")
|
||||||
|
elif raw_data["retcode"] == 10101:
|
||||||
|
# return ("当前cookies已达到30人上限!")
|
||||||
|
errorDB(use_cookies, "limit30")
|
||||||
|
elif raw_data["retcode"] == 10102:
|
||||||
|
return "当前查询id已经设置了隐私,无法查询!"
|
||||||
|
else:
|
||||||
|
return (
|
||||||
|
"Api报错,返回内容为:\r\n"
|
||||||
|
+ str(raw_data) + "\r\n出现这种情况可能的UID输入错误 or 不存在"
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
break
|
||||||
|
|
||||||
|
# 获取数据
|
||||||
|
raw_data = raw_data["data"]
|
||||||
|
raw_char_data = raw_char_data['data']["avatars"]
|
||||||
|
|
||||||
|
# 获取查询者数据
|
||||||
|
if not raw_data['floors']:
|
||||||
|
return ""
|
||||||
|
floors_data = raw_data['floors'][-1]
|
||||||
|
levels_num = len(floors_data['levels'])
|
||||||
|
|
||||||
|
# 获取背景图片
|
||||||
|
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 image:
|
||||||
|
image_data = image.group(2)
|
||||||
|
edit_bg = Image.open(BytesIO(get(image_data).content))
|
||||||
|
else:
|
||||||
|
edit_bg = Image.open(bg2_path)
|
||||||
|
|
||||||
|
# 确定图片的长宽
|
||||||
|
based_w = 900
|
||||||
|
based_h = 660 + levels_num * 315
|
||||||
|
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, based_w, based_h))
|
||||||
|
|
||||||
|
# 获取背景主色
|
||||||
|
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))
|
||||||
|
|
||||||
|
# 确定贴图路径
|
||||||
|
abyss0_path = os.path.join(TEXT_PATH, "abyss_0.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")
|
||||||
|
avatar_bg_path = os.path.join(TEXT_PATH, "avatar_bg.png")
|
||||||
|
avatar_fg_path = os.path.join(TEXT_PATH, "avatar_fg.png")
|
||||||
|
|
||||||
|
all_mask_path = os.path.join(TEXT_PATH, "All_Mask.png")
|
||||||
|
|
||||||
|
# 转换遮罩的颜色、大小匹配,并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)
|
||||||
|
|
||||||
|
# 开启图片
|
||||||
|
avatar_bg = Image.open(avatar_bg_path)
|
||||||
|
avatar_fg = Image.open(avatar_fg_path)
|
||||||
|
|
||||||
|
# 确定主体框架
|
||||||
|
avatar_bg_color = Image.new("RGBA", (316, 100), bg_color)
|
||||||
|
bg_img.paste(avatar_bg_color, (113, 98), avatar_bg)
|
||||||
|
bg_img.paste(avatar_fg, (114, 95), avatar_fg)
|
||||||
|
|
||||||
|
"""
|
||||||
|
x1, y1 = 65, 276
|
||||||
|
radius = 15
|
||||||
|
cropped_img1 = bg_img.crop((x1, y1, 836, 607))
|
||||||
|
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 = 65, 630 + 315*i
|
||||||
|
radius = 15
|
||||||
|
cropped_img2 = bg_img.crop((x2, y2, 836, 925+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_bg_color = Image.new("RGBA", (900, 620), new_color)
|
||||||
|
abyss0 = Image.new("RGBA", (900, 620), (0, 0, 0, 0))
|
||||||
|
|
||||||
|
abyss0_pic = Image.open(abyss0_path)
|
||||||
|
abyss0.paste(abyss0_bg_color, (0, 0), abyss0_pic)
|
||||||
|
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_char_done_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),
|
||||||
|
genshin_font(18), anchor="mm")
|
||||||
|
char_draw.text((95.3, 19), f'{str(k["actived_constellation_num"])}', 'white', genshin_font(18))
|
||||||
|
if str(k["fetter"]) == "10" or str(k["name"]) == "旅行者":
|
||||||
|
char_draw.text((93, 41.5), "♥", (21, 21, 21), genshin_font(15))
|
||||||
|
else:
|
||||||
|
char_draw.text((95.3, 40.5), f'{str(k["fetter"])}', (21, 21, 21), genshin_font(18))
|
||||||
|
char_crop = (82 + 130 * i, 300)
|
||||||
|
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_char_done_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),
|
||||||
|
genshin_font(18), anchor="mm")
|
||||||
|
char_draw.text((95.3, 19), f'{str(k["actived_constellation_num"])}', 'white', genshin_font(18))
|
||||||
|
if str(k["fetter"]) == "10" or str(k["name"]) == "旅行者":
|
||||||
|
char_draw.text((93, 41.5), "♥", (21, 21, 21), genshin_font(15))
|
||||||
|
else:
|
||||||
|
char_draw.text((95.3, 40.5), f'{str(k["fetter"])}', (21, 21, 21), genshin_font(18))
|
||||||
|
char_crop = (685, 470)
|
||||||
|
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["defeat_rank"][i]["avatar_id"]) + ".png")):
|
||||||
|
get_char_done_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),
|
||||||
|
genshin_font(18), anchor="mm")
|
||||||
|
char_draw.text((95.3, 19), f'{str(k["actived_constellation_num"])}', 'white', genshin_font(18))
|
||||||
|
if str(k["fetter"]) == "10" or str(k["name"]) == "旅行者":
|
||||||
|
char_draw.text((93, 41.5), "♥", (21, 21, 21), genshin_font(15))
|
||||||
|
else:
|
||||||
|
char_draw.text((95.3, 40.5), f'{str(k["fetter"])}', (21, 21, 21), genshin_font(18))
|
||||||
|
char_crop = (82 + 123 * i, 470)
|
||||||
|
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["take_damage_rank"][i]["avatar_id"]) + ".png")):
|
||||||
|
get_char_done_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),
|
||||||
|
genshin_font(18), anchor="mm")
|
||||||
|
char_draw.text((95.3, 19), f'{str(k["actived_constellation_num"])}', 'white', genshin_font(18))
|
||||||
|
if str(k["fetter"]) == "10" or str(k["name"]) == "旅行者":
|
||||||
|
char_draw.text((93, 41.5), "♥", (21, 21, 21), genshin_font(15))
|
||||||
|
else:
|
||||||
|
char_draw.text((95.3, 40.5), f'{str(k["fetter"])}', (21, 21, 21), genshin_font(18))
|
||||||
|
char_crop = (232 + 123 * i, 470)
|
||||||
|
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["normal_skill_rank"][i]["avatar_id"]) + ".png")):
|
||||||
|
get_char_done_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),
|
||||||
|
genshin_font(18), anchor="mm")
|
||||||
|
char_draw.text((95.3, 19), f'{str(k["actived_constellation_num"])}', 'white', genshin_font(18))
|
||||||
|
if str(k["fetter"]) == "10" or str(k["name"]) == "旅行者":
|
||||||
|
char_draw.text((93, 41.5), "♥", (21, 21, 21), genshin_font(15))
|
||||||
|
else:
|
||||||
|
char_draw.text((95.3, 40.5), f'{str(k["fetter"])}', (21, 21, 21), genshin_font(18))
|
||||||
|
char_crop = (382 + 123 * i, 470)
|
||||||
|
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["energy_skill_rank"][i]["avatar_id"]) + ".png")):
|
||||||
|
get_char_done_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),
|
||||||
|
genshin_font(18), anchor="mm")
|
||||||
|
char_draw.text((95.3, 19), f'{str(k["actived_constellation_num"])}', 'white', genshin_font(18))
|
||||||
|
if str(k["fetter"]) == "10" or str(k["name"]) == "旅行者":
|
||||||
|
char_draw.text((93, 41.5), "♥", (21, 21, 21), genshin_font(15))
|
||||||
|
else:
|
||||||
|
char_draw.text((95.3, 40.5), f'{str(k["fetter"])}', (21, 21, 21), genshin_font(18))
|
||||||
|
char_crop = (532 + 123 * i, 470)
|
||||||
|
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.new("RGBA", (900, 340), (0, 0, 0, 0))
|
||||||
|
# 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_char_done_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), genshin_font(18))
|
||||||
|
char_draw.text((95.3, 19), f'{str(k["actived_constellation_num"])}', 'white', genshin_font(18))
|
||||||
|
if str(k["fetter"]) == "10" or str(k["name"]) == "旅行者":
|
||||||
|
char_draw.text((93, 41.5), "♥", (21, 21, 21), genshin_font(15))
|
||||||
|
else:
|
||||||
|
char_draw.text((95.3, 40.5), f'{str(k["fetter"])}', (21, 21, 21), genshin_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_char_done_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), genshin_font(18))
|
||||||
|
char_draw.text((95.3, 19), f'{str(k["actived_constellation_num"])}', 'white', genshin_font(18))
|
||||||
|
if str(k["fetter"]) == "10" or str(k["name"]) == "旅行者":
|
||||||
|
char_draw.text((93, 41.5), "♥", (21, 21, 21), genshin_font(15))
|
||||||
|
else:
|
||||||
|
char_draw.text((95.3, 40.5), f'{str(k["fetter"])}', (21, 21, 21), genshin_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}间", new_color, genshin_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}", new_color, genshin_font(19))
|
||||||
|
bg_img.paste(abyss2, (0, 605 + j * 315), abyss2)
|
||||||
|
|
||||||
|
bg_img.paste(abyss3, (0, len(floors_data["levels"]) * 315 + 610), abyss3)
|
||||||
|
|
||||||
|
text_draw = ImageDraw.Draw(bg_img)
|
||||||
|
text_draw.text((220, 123), f"{nickname}", new_color, genshin_font(32))
|
||||||
|
text_draw.text((235, 163), 'UID ' + f"{uid}", new_color, genshin_font(14))
|
||||||
|
|
||||||
|
text_draw.text((690, 82), raw_data['max_floor'], new_color, genshin_font(26))
|
||||||
|
text_draw.text((690, 127), str(raw_data['total_battle_times']), new_color, genshin_font(26))
|
||||||
|
text_draw.text((690, 172), str(raw_data['total_star']), new_color, genshin_font(26))
|
||||||
|
|
||||||
|
bg_img = bg_img.convert('RGB')
|
||||||
|
bg_img.save(f"temp{os.sep}abyss.jpg", format='JPEG', subsampling=0, quality=90)
|
||||||
|
# bg_img.save(result_buffer, format='PNG')
|
||||||
|
return f"temp{os.sep}abyss.jpg"
|
||||||
|
|
||||||
|
|
||||||
|
async def draw_abyss_pic(uid, nickname, floor_num, image=None, mode=2, date="1"):
|
||||||
|
while True:
|
||||||
|
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)
|
||||||
|
for i in mys_data['data']['list']:
|
||||||
|
if i['game_id'] != 2:
|
||||||
|
mys_data['data']['list'].remove(i)
|
||||||
|
uid = mys_data['data']['list'][0]['game_role_id']
|
||||||
|
nickname = mys_data['data']['list'][0]['nickname']
|
||||||
|
|
||||||
|
raw_data = await get_spiral_abyss_info(uid, use_cookies, date)
|
||||||
|
raw_char_data = await GetInfo(uid, use_cookies)
|
||||||
|
|
||||||
|
if raw_data["retcode"] != 0:
|
||||||
|
if raw_data["retcode"] == 10001:
|
||||||
|
# return ("Cookie错误/过期,请重置Cookie")
|
||||||
|
errorDB(use_cookies, "error")
|
||||||
|
elif raw_data["retcode"] == 10101:
|
||||||
|
# return ("当前cookies已达到30人上限!")
|
||||||
|
errorDB(use_cookies, "limit30")
|
||||||
|
elif raw_data["retcode"] == 10102:
|
||||||
|
return "当前查询id已经设置了隐私,无法查询!"
|
||||||
|
else:
|
||||||
|
return (
|
||||||
|
"Api报错,返回内容为:\r\n"
|
||||||
|
+ str(raw_data) + "\r\n出现这种情况可能的UID输入错误 or 不存在"
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
break
|
||||||
|
|
||||||
|
# 获取数据
|
||||||
|
raw_data = raw_data["data"]
|
||||||
|
raw_char_data = raw_char_data['data']["avatars"]
|
||||||
|
floors_data = raw_data['floors']
|
||||||
|
if not floors_data:
|
||||||
|
return ""
|
||||||
|
based_data = []
|
||||||
|
for i in floors_data:
|
||||||
|
if str(i['index']) == floor_num:
|
||||||
|
based_data = i
|
||||||
|
levels_num = len(based_data['levels'])
|
||||||
|
|
||||||
|
# 获取背景图片
|
||||||
|
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 image:
|
||||||
|
image_data = image.group(2)
|
||||||
|
edit_bg = Image.open(BytesIO(get(image_data).content))
|
||||||
|
else:
|
||||||
|
edit_bg = Image.open(bg2_path)
|
||||||
|
|
||||||
|
# 确定图片的长宽
|
||||||
|
based_w = 900
|
||||||
|
based_h = 440 + levels_num * 340
|
||||||
|
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, based_w, based_h))
|
||||||
|
|
||||||
|
# 获取背景主色
|
||||||
|
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))
|
||||||
|
|
||||||
|
# 打开图片
|
||||||
|
abyss1_path = os.path.join(TEXT_PATH, "abyss_1.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")
|
||||||
|
abyss1 = Image.open(abyss1_path)
|
||||||
|
abyss3 = Image.open(abyss3_path)
|
||||||
|
abyss_star0 = Image.open(abyss_star0_path)
|
||||||
|
abyss_star1 = Image.open(abyss_star1_path)
|
||||||
|
avatar_bg_path = os.path.join(TEXT_PATH, "avatar_bg.png")
|
||||||
|
avatar_fg_path = os.path.join(TEXT_PATH, "avatar_fg.png")
|
||||||
|
|
||||||
|
all_mask_path = os.path.join(TEXT_PATH, "All_Mask.png")
|
||||||
|
|
||||||
|
# 转换遮罩的颜色、大小匹配,并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)
|
||||||
|
|
||||||
|
# 开启图片
|
||||||
|
avatar_bg = Image.open(avatar_bg_path)
|
||||||
|
avatar_fg = Image.open(avatar_fg_path)
|
||||||
|
|
||||||
|
# 确定主体框架
|
||||||
|
avatar_bg_color = Image.new("RGBA", (316, 100), bg_color)
|
||||||
|
bg_img.paste(avatar_bg_color, (113, 145), avatar_bg)
|
||||||
|
bg_img.paste(avatar_fg, (114, 142), avatar_fg)
|
||||||
|
|
||||||
|
"""
|
||||||
|
for i in range(0,len(based_data['levels'])):
|
||||||
|
x, y = 65, 220 + 340*i
|
||||||
|
radius = 10
|
||||||
|
cropped_img = bg_img.crop((x, y, 836, 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))
|
||||||
|
"""
|
||||||
|
|
||||||
|
abyss1_bg_color = Image.new("RGBA", (900, 400), bg_color)
|
||||||
|
bg_img.paste(abyss1_bg_color, (0, 0), abyss1)
|
||||||
|
|
||||||
|
for j in range(0, len(based_data['levels'])):
|
||||||
|
abyss2 = Image.new("RGBA", (900, 340), (0, 0, 0, 0))
|
||||||
|
num_1 = 0
|
||||||
|
avatars = based_data['levels'][j]['battles'][0]['avatars'] + based_data['levels'][j]['battles'][1]['avatars']
|
||||||
|
for i in based_data['levels'][j]['battles'][0]['avatars']:
|
||||||
|
if not os.path.exists(os.path.join(CHAR_DONE_PATH, str(i['id']) + ".png")):
|
||||||
|
get_char_done_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), genshin_font(18))
|
||||||
|
char_draw.text((95.3, 19), f'{str(k["actived_constellation_num"])}', 'white', genshin_font(18))
|
||||||
|
if str(k["fetter"]) == "10" or str(k["name"]) == "旅行者":
|
||||||
|
char_draw.text((93, 41.5), "♥", (21, 21, 21), genshin_font(15))
|
||||||
|
else:
|
||||||
|
char_draw.text((95.3, 40.5), f'{str(k["fetter"])}', (21, 21, 21), genshin_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 based_data['levels'][j]['battles'][1]['avatars']:
|
||||||
|
if not os.path.exists(os.path.join(CHAR_DONE_PATH, str(i['id']) + ".png")):
|
||||||
|
get_char_done_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), genshin_font(18))
|
||||||
|
char_draw.text((95.3, 19), f'{str(k["actived_constellation_num"])}', 'white', genshin_font(18))
|
||||||
|
if str(k["fetter"]) == "10" or str(k["name"]) == "旅行者":
|
||||||
|
char_draw.text((93, 41.5), "♥", (21, 21, 21), genshin_font(15))
|
||||||
|
else:
|
||||||
|
char_draw.text((95.3, 40.5), f'{str(k["fetter"])}', (21, 21, 21), genshin_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 = based_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}间", new_color, genshin_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((167, 33), f"{otherStyleTime1}/{otherStyleTime2}", new_color, genshin_font(19))
|
||||||
|
bg_img.paste(abyss2, (0, 350 + j * 340), abyss2)
|
||||||
|
|
||||||
|
bg_img.paste(abyss3, (0, len(based_data['levels']) * 340 + 400), abyss3)
|
||||||
|
|
||||||
|
text_draw = ImageDraw.Draw(bg_img)
|
||||||
|
|
||||||
|
text_draw.text((220, 163), f"{nickname}", new_color, genshin_font(32))
|
||||||
|
text_draw.text((235, 203), 'UID ' + f"{uid}", new_color, genshin_font(14))
|
||||||
|
text_draw.text((710, 190), f"{floor_num}", new_color, genshin_font(50), anchor="mm")
|
||||||
|
|
||||||
|
bg_img = bg_img.convert('RGB')
|
||||||
|
result_buffer = BytesIO()
|
||||||
|
bg_img.save(f"temp{os.sep}abyss.jpg", format='JPEG', subsampling=0, quality=90)
|
||||||
|
# bg_img.save(result_buffer, format='PNG')
|
||||||
|
return f"temp{os.sep}abyss.jpg"
|
233
defs/spiral_abyss_text.py
Normal file
233
defs/spiral_abyss_text.py
Normal file
@ -0,0 +1,233 @@
|
|||||||
|
import json
|
||||||
|
import os
|
||||||
|
import time
|
||||||
|
|
||||||
|
from defs.db import GetInfo, cacheDB, GetMysInfo, get_spiral_abyss_info, errorDB
|
||||||
|
from pydantic import BaseModel
|
||||||
|
from typing import List
|
||||||
|
|
||||||
|
|
||||||
|
class GenshinUserCharacher(BaseModel):
|
||||||
|
id: int
|
||||||
|
image: str # 角色头图url
|
||||||
|
name: str # 角色名
|
||||||
|
element: str # 属性
|
||||||
|
fetter: int # 好感等级
|
||||||
|
level: int
|
||||||
|
rarity: int # 稀有度
|
||||||
|
actived_constellation_num: int # 命之座
|
||||||
|
|
||||||
|
|
||||||
|
class GenshinUserStats(BaseModel):
|
||||||
|
active_day_number: int # 活跃天数
|
||||||
|
achievement_number: int # 成就数
|
||||||
|
win_rate: int
|
||||||
|
anemoculus_number: int # 风神瞳数量
|
||||||
|
geoculus_number: int # 岩神瞳数
|
||||||
|
electroculus_number: int # 雷神瞳数量
|
||||||
|
avatar_number: int # 角色数量
|
||||||
|
way_point_number: int # 传送点解锁数
|
||||||
|
domain_number: int # 秘境解锁数
|
||||||
|
spiral_abyss: str # 深渊进度
|
||||||
|
common_chest_number: int # 普通宝箱数量
|
||||||
|
exquisite_chest_number: int # 精致宝箱数量
|
||||||
|
precious_chest_number: int # 珍贵宝箱数量
|
||||||
|
luxurious_chest_number: int # 华丽宝箱数量
|
||||||
|
magic_chest_number: int # 奇馈宝箱数量
|
||||||
|
|
||||||
|
|
||||||
|
class GenshinWorldOfferings(BaseModel):
|
||||||
|
name: str
|
||||||
|
level: int
|
||||||
|
|
||||||
|
|
||||||
|
class GenshinWorldInfo(BaseModel):
|
||||||
|
level: int # 声望等级
|
||||||
|
exploration_percentage: int # 探索度
|
||||||
|
icon: str # 区域图标url
|
||||||
|
name: str
|
||||||
|
type: str
|
||||||
|
id: int
|
||||||
|
offerings: List[GenshinWorldOfferings] # 供奉信息
|
||||||
|
|
||||||
|
|
||||||
|
class GenshinHomeInfo(BaseModel):
|
||||||
|
level: int # 信任等级
|
||||||
|
visit_num: int # 访客数
|
||||||
|
comfort_num: int # 洞天仙力
|
||||||
|
item_num: int # 摆件数量
|
||||||
|
name: str
|
||||||
|
icon: str # 背景图
|
||||||
|
comfort_level_name: str # 洞天仙力对应名称
|
||||||
|
comfort_level_icon: str # 等级图标
|
||||||
|
|
||||||
|
|
||||||
|
class GenshinUserData(BaseModel):
|
||||||
|
avatars: List[GenshinUserCharacher] # 角色列表
|
||||||
|
stats: GenshinUserStats
|
||||||
|
city_explorations: List # 不知道是啥玩意, 都是空的
|
||||||
|
world_explorations: List[GenshinWorldInfo] # 区域探索信息
|
||||||
|
homes: List[GenshinHomeInfo] # 家园信息
|
||||||
|
|
||||||
|
|
||||||
|
class GenshinAbyssRankInfo(BaseModel):
|
||||||
|
avatar_id: int
|
||||||
|
avatar_icon: str
|
||||||
|
value: int
|
||||||
|
rarity: int
|
||||||
|
|
||||||
|
|
||||||
|
class GenshinAbyssFloorInfoBattlesAvatars(BaseModel):
|
||||||
|
id: int
|
||||||
|
icon: str
|
||||||
|
level: int
|
||||||
|
rarity: int
|
||||||
|
|
||||||
|
|
||||||
|
class GenshinAbyssFloorInfoBattles(BaseModel):
|
||||||
|
index: int # 战斗场次
|
||||||
|
timestamp: str
|
||||||
|
avatars: List[GenshinAbyssFloorInfoBattlesAvatars]
|
||||||
|
|
||||||
|
|
||||||
|
class GenshinAbyssFloorInfo(BaseModel):
|
||||||
|
index: int # 间号
|
||||||
|
star: int
|
||||||
|
max_star: int
|
||||||
|
battles: List[GenshinAbyssFloorInfoBattles]
|
||||||
|
|
||||||
|
|
||||||
|
class GenshinAbyssFloors(BaseModel):
|
||||||
|
index: int # 层数
|
||||||
|
icon: str # 空的
|
||||||
|
is_unlock: bool
|
||||||
|
settle_time: str
|
||||||
|
star: int
|
||||||
|
max_star: int
|
||||||
|
levels: List[GenshinAbyssFloorInfo]
|
||||||
|
|
||||||
|
|
||||||
|
class GenshinAbyss(BaseModel):
|
||||||
|
schedule_id: int
|
||||||
|
start_time: int # 10位
|
||||||
|
end_time: int # 10位
|
||||||
|
total_battle_times: int
|
||||||
|
total_win_times: int
|
||||||
|
max_floor: str
|
||||||
|
reveal_rank: List[GenshinAbyssRankInfo] # 出战次数Rank
|
||||||
|
defeat_rank: List[GenshinAbyssRankInfo] # 击破数Rank
|
||||||
|
damage_rank: List[GenshinAbyssRankInfo] # 最强一击
|
||||||
|
take_damage_rank: List[GenshinAbyssRankInfo] # 承伤Rank
|
||||||
|
normal_skill_rank: List[GenshinAbyssRankInfo] # 元素战技释放数
|
||||||
|
energy_skill_rank: List[GenshinAbyssRankInfo] # 元素爆发次数
|
||||||
|
floors: List[GenshinAbyssFloors]
|
||||||
|
total_star: int
|
||||||
|
is_unlock: bool
|
||||||
|
|
||||||
|
|
||||||
|
def char_id_to_name(udata: GenshinUserData, charid: int): # id2name.json数据不全, 我也懒得去搜集了, 故采用此邪道方法(
|
||||||
|
chars = udata.avatars
|
||||||
|
for char in chars:
|
||||||
|
if charid == char.id:
|
||||||
|
return char.name
|
||||||
|
with open(f"assets{os.sep}data{os.sep}id2name.json", "r", encoding="utf-8") as f:
|
||||||
|
id2name = json.load(f)
|
||||||
|
if str(charid) in id2name:
|
||||||
|
return id2name[str(charid)]
|
||||||
|
return f"{charid}"
|
||||||
|
|
||||||
|
|
||||||
|
def timestamp_to_text(timestamp: int, _format="%Y-%m-%d %H:%M:%S"):
|
||||||
|
"""
|
||||||
|
:param timestamp: 时间戳,若输入13位时间戳则自动转为10位
|
||||||
|
:param _format: 格式,默认"%Y-%m-%d %H:%M:%S"
|
||||||
|
:return: %Y-%m-%d %H:%M:%S -> str
|
||||||
|
"""
|
||||||
|
if timestamp > 9999999999: # 13位时间戳转10位
|
||||||
|
timestamp = timestamp / 1000
|
||||||
|
ret = time.strftime(_format, time.localtime(timestamp))
|
||||||
|
return ret
|
||||||
|
|
||||||
|
|
||||||
|
async def get_user_abyss(uid, mode=2, date="1"): # 深境螺旋
|
||||||
|
# 获取Cookies
|
||||||
|
while True:
|
||||||
|
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)
|
||||||
|
for i in mys_data['data']['list']:
|
||||||
|
if i['game_id'] != 2:
|
||||||
|
mys_data['data']['list'].remove(i)
|
||||||
|
uid = mys_data['data']['list'][0]['game_role_id']
|
||||||
|
nickname = mys_data['data']['list'][0]['nickname']
|
||||||
|
|
||||||
|
raw_data = await get_spiral_abyss_info(uid, use_cookies, date)
|
||||||
|
raw_char_data = await GetInfo(uid, use_cookies)
|
||||||
|
|
||||||
|
if raw_data["retcode"] != 0:
|
||||||
|
if raw_data["retcode"] == 10001:
|
||||||
|
# return ("Cookie错误/过期,请重置Cookie")
|
||||||
|
errorDB(use_cookies, "error")
|
||||||
|
elif raw_data["retcode"] == 10101:
|
||||||
|
# return ("当前cookies已达到30人上限!")
|
||||||
|
errorDB(use_cookies, "limit30")
|
||||||
|
elif raw_data["retcode"] == 10102:
|
||||||
|
return "当前查询id已经设置了隐私,无法查询!"
|
||||||
|
else:
|
||||||
|
return (
|
||||||
|
"Api报错,返回内容为:\r\n"
|
||||||
|
+ str(raw_data) + "\r\n出现这种情况可能的UID输入错误 or 不存在"
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
break
|
||||||
|
|
||||||
|
# 获取数据
|
||||||
|
udata = GenshinUserData(**raw_char_data["data"])
|
||||||
|
aby = GenshinAbyss(**raw_data["data"])
|
||||||
|
breakpoint()
|
||||||
|
if not aby.floors: # 没打
|
||||||
|
return ""
|
||||||
|
rettext = f"<b>第{aby.schedule_id}期深境螺旋信息</b>\n\n" \
|
||||||
|
f"\t开始时间: {timestamp_to_text(aby.start_time)}\n" \
|
||||||
|
f"\t结束时间: {timestamp_to_text(aby.end_time)}\n" \
|
||||||
|
f"\t最深抵达:{aby.max_floor}\n" \
|
||||||
|
f"\t胜利场次/总场次: {aby.total_win_times}/{aby.total_battle_times}\n"
|
||||||
|
if aby.reveal_rank:
|
||||||
|
rettext += f"\t出战最多: {char_id_to_name(udata, aby.reveal_rank[0].avatar_id)} - {aby.reveal_rank[0].value}\n"
|
||||||
|
if aby.defeat_rank:
|
||||||
|
rettext += f"\t击破最多: {char_id_to_name(udata, aby.defeat_rank[0].avatar_id)} - {aby.defeat_rank[0].value}\n"
|
||||||
|
if aby.damage_rank:
|
||||||
|
rettext += f"\t最强一击: {char_id_to_name(udata, aby.damage_rank[0].avatar_id)} - {aby.damage_rank[0].value}\n"
|
||||||
|
if aby.take_damage_rank:
|
||||||
|
rettext += f"\t最高承伤: {char_id_to_name(udata, aby.take_damage_rank[0].avatar_id)} - {aby.take_damage_rank[0].value}\n"
|
||||||
|
if aby.normal_skill_rank:
|
||||||
|
rettext += f"\t元素战技: {char_id_to_name(udata, aby.normal_skill_rank[0].avatar_id)} - {aby.normal_skill_rank[0].value}\n"
|
||||||
|
if aby.energy_skill_rank:
|
||||||
|
rettext += f"\t元素爆发: {char_id_to_name(udata, aby.energy_skill_rank[0].avatar_id)} - {aby.energy_skill_rank[0].value}\n"
|
||||||
|
rettext += f"\t总星数: ★ {aby.total_star}\n\t"
|
||||||
|
|
||||||
|
floor_text = "" # 层
|
||||||
|
has_details = False
|
||||||
|
if len(aby.floors) >= 0:
|
||||||
|
if len(aby.floors[0].levels) > 0:
|
||||||
|
has_details = True
|
||||||
|
for floor in aby.floors: # 层
|
||||||
|
room_text = "" # 间
|
||||||
|
for room in floor.levels: # 间
|
||||||
|
battle_text = "" # 场
|
||||||
|
for battle in room.battles: # 场次
|
||||||
|
character_text = "" # 角色
|
||||||
|
for char in battle.avatars: # 角色列表
|
||||||
|
character_text += f"/{char_id_to_name(udata, char.id)}"
|
||||||
|
battle_text += f"\n\t\t\t\t第 {battle.index} 场: {character_text[1:]}"
|
||||||
|
|
||||||
|
room_text += f"\n\t\t\t第 {room.index} 间 (★ {room.star}/{room.max_star}):{battle_text}"
|
||||||
|
|
||||||
|
floor_text += f"\n\n\t\t第 {floor.index} 层:\t{room_text}"
|
||||||
|
rettext = f"{rettext}楼层信息:{floor_text}" if has_details else f"{rettext}未获取到详细楼层信息"
|
||||||
|
return rettext
|
@ -2,6 +2,7 @@ from pyrogram import Client
|
|||||||
from pyrogram.types import Message
|
from pyrogram.types import Message
|
||||||
from os import getcwd, sep
|
from os import getcwd, sep
|
||||||
from defs.challenge import get_day
|
from defs.challenge import get_day
|
||||||
|
from defs.redis_load import redis_status, redis
|
||||||
|
|
||||||
|
|
||||||
async def tf_msg(client: Client, message: Message):
|
async def tf_msg(client: Client, message: Message):
|
||||||
@ -23,4 +24,18 @@ async def wq_msg(client: Client, message: Message):
|
|||||||
|
|
||||||
|
|
||||||
async def zb_msg(client: Client, message: Message):
|
async def zb_msg(client: Client, message: Message):
|
||||||
await message.reply_photo(photo=f'{getcwd()}{sep}assets{sep}images{sep}zb.png', quote=True)
|
if redis_status():
|
||||||
|
try:
|
||||||
|
data = redis.get("zb").decode()
|
||||||
|
except AttributeError:
|
||||||
|
data = None
|
||||||
|
if data != "2.5":
|
||||||
|
# 开始上传
|
||||||
|
msg = await message.reply_photo(photo=f"{getcwd()}{sep}assets{sep}images{sep}zb.png", quote=True)
|
||||||
|
# 缓存 file_id
|
||||||
|
redis.set("zb", "2.5")
|
||||||
|
redis.set("zb_file_id", msg.document.file_id)
|
||||||
|
else:
|
||||||
|
await message.reply_photo(photo=redis.get('zb_file_id').decode(), quote=True)
|
||||||
|
else:
|
||||||
|
await message.reply_photo(photo=f'{getcwd()}{sep}assets{sep}images{sep}zb.png', quote=True)
|
||||||
|
28
plugins/char_adv.py
Normal file
28
plugins/char_adv.py
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
from pyrogram import Client
|
||||||
|
from pyrogram.types import Message
|
||||||
|
from traceback import print_exc
|
||||||
|
from defs.char_adv import char_adv, weapon_adv
|
||||||
|
|
||||||
|
|
||||||
|
async def send_char_adv(client: Client, message: Message):
|
||||||
|
try:
|
||||||
|
name = message.text
|
||||||
|
for i in ["用什么", "能用啥", "怎么养"]:
|
||||||
|
name = name.replace(i, "").strip()
|
||||||
|
im = await char_adv(name)
|
||||||
|
await message.reply(im, quote=True)
|
||||||
|
except Exception as e:
|
||||||
|
print("获取建议失败。")
|
||||||
|
print_exc()
|
||||||
|
|
||||||
|
|
||||||
|
async def send_weapon_adv(client: Client, message: Message):
|
||||||
|
try:
|
||||||
|
name = message.text
|
||||||
|
for i in ["能给谁", "给谁用", "要给谁", "谁能用"]:
|
||||||
|
name = name.replace(i, "").strip()
|
||||||
|
im = await weapon_adv(name)
|
||||||
|
await message.reply(im, quote=True)
|
||||||
|
except Exception as e:
|
||||||
|
print("获取建议失败。")
|
||||||
|
print_exc()
|
157
plugins/mys2.py
157
plugins/mys2.py
@ -15,6 +15,8 @@ from defs.mihoyo import draw_pic as draw_pic_2
|
|||||||
|
|
||||||
from ci import scheduler, app, admin_id
|
from ci import scheduler, app, admin_id
|
||||||
from defs.redis_load import redis
|
from defs.redis_load import redis
|
||||||
|
from defs.spiral_abyss import draw_abyss_pic, draw_abyss0_pic
|
||||||
|
from defs.spiral_abyss_text import get_user_abyss
|
||||||
|
|
||||||
SUPERUSERS = [admin_id]
|
SUPERUSERS = [admin_id]
|
||||||
|
|
||||||
@ -195,26 +197,89 @@ async def mys2_qun_msg(client: Client, message: Message):
|
|||||||
elif "uid" in text:
|
elif "uid" in text:
|
||||||
try:
|
try:
|
||||||
uid = re.findall(r"\d+", text)[0] # str
|
uid = re.findall(r"\d+", text)[0] # str
|
||||||
|
m = ''.join(re.findall('[\u4e00-\u9fa5]', text))
|
||||||
except IndexError:
|
except IndexError:
|
||||||
return await message.reply("uid格式错误!")
|
return await message.reply("uid格式错误!")
|
||||||
try:
|
nickname = message.from_user.first_name
|
||||||
|
nickname = nickname if len(nickname) < 10 else (nickname[:10] + "...")
|
||||||
|
if m == "深渊":
|
||||||
try:
|
try:
|
||||||
nickname = message.from_user.first_name
|
if len(re.findall(r"\d+", text)) == 2:
|
||||||
nickname = nickname if len(nickname) < 10 else (nickname[:10] + "...")
|
floor_num = re.findall(r"\d+", text)[1]
|
||||||
if is_chinese(uid):
|
im = await draw_abyss_pic(uid, nickname, floor_num)
|
||||||
im = await draw_pic(uid, message, nickname=nickname, mode=2)
|
if not im:
|
||||||
|
await message.reply("未查找到该用户的深渊信息。")
|
||||||
|
else:
|
||||||
|
await message.reply_photo(im)
|
||||||
else:
|
else:
|
||||||
im = await draw_pic_2(uid, message, nickname=nickname, mode=2)
|
im = await draw_abyss0_pic(uid, nickname)
|
||||||
if im.find(".") != -1:
|
if not im:
|
||||||
await message.reply_photo(im)
|
await message.reply("未查找到该用户的深渊信息。")
|
||||||
else:
|
else:
|
||||||
await message.reply(im)
|
await message.reply_photo(im)
|
||||||
|
except TypeError:
|
||||||
|
await message.reply("获取失败,可能是Cookies失效或者未打开米游社角色详情开关。")
|
||||||
|
print("上期深渊数据获取失败(Cookie失效/不公开信息)")
|
||||||
|
traceback.print_exc()
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
await message.reply("获取失败,有可能是数据状态有问题,\n{}\n请检查后台输出。".format(e))
|
await message.reply("获取失败,有可能是数据状态有问题,\n{}\n请检查后台输出。".format(e))
|
||||||
|
print("上期深渊数据获取失败(数据状态问题)")
|
||||||
traceback.print_exc()
|
traceback.print_exc()
|
||||||
except Exception as e:
|
elif m == "上期深渊":
|
||||||
traceback.print_exc()
|
try:
|
||||||
await message.reply("发生错误 {},请检查后台输出。".format(e))
|
if len(re.findall(r"\d+", text)) == 2:
|
||||||
|
floor_num = re.findall(r"\d+", text)[1]
|
||||||
|
im = await draw_abyss_pic(uid, nickname, floor_num, None, 2, "2")
|
||||||
|
if not im:
|
||||||
|
await message.reply("未查找到该用户的深渊信息。")
|
||||||
|
else:
|
||||||
|
await message.reply_photo(im)
|
||||||
|
else:
|
||||||
|
im = await draw_abyss0_pic(uid, nickname, None, 2, "2")
|
||||||
|
if not im:
|
||||||
|
await message.reply("未查找到该用户的深渊信息。")
|
||||||
|
else:
|
||||||
|
await message.reply_photo(im)
|
||||||
|
except TypeError:
|
||||||
|
await message.reply("获取失败,可能是Cookies失效或者未打开米游社角色详情开关。")
|
||||||
|
print("上期深渊数据获取失败(Cookie失效/不公开信息)")
|
||||||
|
traceback.print_exc()
|
||||||
|
except Exception as e:
|
||||||
|
await message.reply("获取失败,有可能是数据状态有问题,\n{}\n请检查后台输出。".format(e))
|
||||||
|
print("上期深渊数据获取失败(数据状态问题)")
|
||||||
|
traceback.print_exc()
|
||||||
|
elif m == "文本深渊":
|
||||||
|
try:
|
||||||
|
im = await get_user_abyss(uid, 2, "2")
|
||||||
|
if not im:
|
||||||
|
await message.reply("未查找到该用户的深渊信息。")
|
||||||
|
else:
|
||||||
|
await message.reply(im)
|
||||||
|
except TypeError:
|
||||||
|
await message.reply("获取失败,可能是Cookies失效或者未打开米游社角色详情开关。")
|
||||||
|
print("上期深渊数据获取失败(Cookie失效/不公开信息)")
|
||||||
|
traceback.print_exc()
|
||||||
|
except Exception as e:
|
||||||
|
await message.reply("获取失败,有可能是数据状态有问题,\n{}\n请检查后台输出。".format(e))
|
||||||
|
print("上期深渊数据获取失败(数据状态问题)")
|
||||||
|
traceback.print_exc()
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
try:
|
||||||
|
if is_chinese(uid):
|
||||||
|
im = await draw_pic(uid, message, nickname=nickname, mode=2)
|
||||||
|
else:
|
||||||
|
im = await draw_pic_2(uid, message, nickname=nickname, mode=2)
|
||||||
|
if im.find(".") != -1:
|
||||||
|
await message.reply_photo(im)
|
||||||
|
else:
|
||||||
|
await message.reply(im)
|
||||||
|
except Exception as e:
|
||||||
|
await message.reply("获取失败,有可能是数据状态有问题,\n{}\n请检查后台输出。".format(e))
|
||||||
|
traceback.print_exc()
|
||||||
|
except Exception as e:
|
||||||
|
traceback.print_exc()
|
||||||
|
await message.reply("发生错误 {},请检查后台输出。".format(e))
|
||||||
elif "查询" in text:
|
elif "查询" in text:
|
||||||
try:
|
try:
|
||||||
at = message.reply_to_message
|
at = message.reply_to_message
|
||||||
@ -227,7 +292,68 @@ async def mys2_qun_msg(client: Client, message: Message):
|
|||||||
uid = await selectDB(message.from_user.id)
|
uid = await selectDB(message.from_user.id)
|
||||||
nickname = nickname if len(nickname) < 10 else (nickname[:10] + "...")
|
nickname = nickname if len(nickname) < 10 else (nickname[:10] + "...")
|
||||||
if uid:
|
if uid:
|
||||||
if "词云" in text:
|
if "深渊" in text and "上期" not in text and "文本" not in text:
|
||||||
|
try:
|
||||||
|
if len(re.findall(r"\d+", text)) == 1:
|
||||||
|
floor_num = re.findall(r"\d+", text)[0]
|
||||||
|
im = await draw_abyss_pic(uid[0], nickname, floor_num, None, uid[1])
|
||||||
|
if not im:
|
||||||
|
await message.reply("未查找到该用户的深渊信息。")
|
||||||
|
else:
|
||||||
|
await message.reply_photo(im)
|
||||||
|
else:
|
||||||
|
im = await draw_abyss0_pic(uid[0], nickname, None, uid[1])
|
||||||
|
if not im:
|
||||||
|
await message.reply("未查找到该用户的深渊信息。")
|
||||||
|
else:
|
||||||
|
await message.reply_photo(im)
|
||||||
|
except TypeError:
|
||||||
|
await message.reply("获取失败,可能是Cookies失效或者未打开米游社角色详情开关。")
|
||||||
|
print("上期深渊数据获取失败(Cookie失效/不公开信息)")
|
||||||
|
traceback.print_exc()
|
||||||
|
except Exception as e:
|
||||||
|
await message.reply("获取失败,有可能是数据状态有问题,\n{}\n请检查后台输出。".format(e))
|
||||||
|
print("上期深渊数据获取失败(数据状态问题)")
|
||||||
|
traceback.print_exc()
|
||||||
|
elif "深渊" in text and "文本" not in text:
|
||||||
|
try:
|
||||||
|
if len(re.findall(r"\d+", text)) == 1:
|
||||||
|
floor_num = re.findall(r"\d+", text)[0]
|
||||||
|
im = await draw_abyss_pic(uid[0], nickname, floor_num, None, uid[1], "2")
|
||||||
|
if not im:
|
||||||
|
await message.reply("未查找到该用户的深渊信息。")
|
||||||
|
else:
|
||||||
|
await message.reply_photo(im)
|
||||||
|
else:
|
||||||
|
im = await draw_abyss0_pic(uid[0], nickname, None, uid[1], "2")
|
||||||
|
if not im:
|
||||||
|
await message.reply("未查找到该用户的深渊信息。")
|
||||||
|
else:
|
||||||
|
await message.reply_photo(im)
|
||||||
|
except TypeError:
|
||||||
|
await message.reply("获取失败,可能是Cookies失效或者未打开米游社角色详情开关。")
|
||||||
|
print("上期深渊数据获取失败(Cookie失效/不公开信息)")
|
||||||
|
traceback.print_exc()
|
||||||
|
except Exception as e:
|
||||||
|
await message.reply("获取失败,有可能是数据状态有问题,\n{}\n请检查后台输出。".format(e))
|
||||||
|
print("上期深渊数据获取失败(数据状态问题)")
|
||||||
|
traceback.print_exc()
|
||||||
|
elif "深渊" in text:
|
||||||
|
try:
|
||||||
|
im = await get_user_abyss(uid[0], uid[1], "2")
|
||||||
|
if not im:
|
||||||
|
await message.reply("未查找到该用户的深渊信息。")
|
||||||
|
else:
|
||||||
|
await message.reply(im)
|
||||||
|
except TypeError:
|
||||||
|
await message.reply("获取失败,可能是Cookies失效或者未打开米游社角色详情开关。")
|
||||||
|
print("上期深渊数据获取失败(Cookie失效/不公开信息)")
|
||||||
|
traceback.print_exc()
|
||||||
|
except Exception as e:
|
||||||
|
await message.reply("获取失败,有可能是数据状态有问题,\n{}\n请检查后台输出。".format(e))
|
||||||
|
print("上期深渊数据获取失败(数据状态问题)")
|
||||||
|
traceback.print_exc()
|
||||||
|
elif "词云" in text:
|
||||||
try:
|
try:
|
||||||
im = await draw_wordcloud(uid[0], message, uid[1])
|
im = await draw_wordcloud(uid[0], message, uid[1])
|
||||||
if im.find(".jpg") != -1:
|
if im.find(".jpg") != -1:
|
||||||
@ -300,7 +426,8 @@ async def push():
|
|||||||
if i['gid'] == "on":
|
if i['gid'] == "on":
|
||||||
await app.send_message(int(i['qid']), i['message'])
|
await app.send_message(int(i['qid']), i['message'])
|
||||||
else:
|
else:
|
||||||
await app.send_message(int(i['gid']), f"[NOTICE {i['qid']}](tg://user?id={i['qid']})" + "\n" + i['message'])
|
await app.send_message(int(i['gid']),
|
||||||
|
f"[NOTICE {i['qid']}](tg://user?id={i['qid']})" + "\n" + i['message'])
|
||||||
else:
|
else:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@ -24,6 +24,7 @@ from plugins.foods import foods_msg
|
|||||||
from plugins.artifacts import artifacts_msg
|
from plugins.artifacts import artifacts_msg
|
||||||
from plugins.artifact_rate import artifact_rate_msg
|
from plugins.artifact_rate import artifact_rate_msg
|
||||||
from plugins.query_resource_points import inquire_resource_points, inquire_resource_list
|
from plugins.query_resource_points import inquire_resource_points, inquire_resource_list
|
||||||
|
from plugins.char_adv import send_char_adv, send_weapon_adv
|
||||||
from plugins.mys import mys_msg, promote_command
|
from plugins.mys import mys_msg, promote_command
|
||||||
|
|
||||||
from defs.inline_query_result_cached_media import InlineQueryResultCachedDocument
|
from defs.inline_query_result_cached_media import InlineQueryResultCachedDocument
|
||||||
@ -115,6 +116,14 @@ async def process_private_msg(client: Client, message: Message):
|
|||||||
await mys2_msg(client, message)
|
await mys2_msg(client, message)
|
||||||
if 'hoyolab' in message.text:
|
if 'hoyolab' in message.text:
|
||||||
await mihoyo_msg(client, message)
|
await mihoyo_msg(client, message)
|
||||||
|
for i in ["用什么", "能用啥", "怎么养"]:
|
||||||
|
if i in message.text:
|
||||||
|
await send_char_adv(client, message)
|
||||||
|
break
|
||||||
|
for i in ["能给谁", "给谁用", "要给谁", "谁能用"]:
|
||||||
|
if i in message.text:
|
||||||
|
await send_weapon_adv(client, message)
|
||||||
|
break
|
||||||
# 账号信息(cookie 过期过快 不推荐启用)
|
# 账号信息(cookie 过期过快 不推荐启用)
|
||||||
# if '账号信息' in message.text or '用户信息' in message.text:
|
# if '账号信息' in message.text or '用户信息' in message.text:
|
||||||
# await mys_msg(client, message)
|
# await mys_msg(client, message)
|
||||||
@ -199,6 +208,15 @@ async def process_group_msg(client: Client, message: Message):
|
|||||||
await guess_voice(client, message)
|
await guess_voice(client, message)
|
||||||
if text.startswith("抽卡"):
|
if text.startswith("抽卡"):
|
||||||
await gacha_msg(client, message)
|
await gacha_msg(client, message)
|
||||||
|
# 建议
|
||||||
|
for i in ["用什么", "能用啥", "怎么养"]:
|
||||||
|
if i in message.text:
|
||||||
|
await send_char_adv(client, message)
|
||||||
|
break
|
||||||
|
for i in ["能给谁", "给谁用", "要给谁", "谁能用"]:
|
||||||
|
if i in message.text:
|
||||||
|
await send_weapon_adv(client, message)
|
||||||
|
break
|
||||||
# 处理猜语音游戏
|
# 处理猜语音游戏
|
||||||
await process_guess(client, message)
|
await process_guess(client, message)
|
||||||
|
|
||||||
|
@ -2,7 +2,8 @@ from ci import admin_id
|
|||||||
from pyrogram import Client
|
from pyrogram import Client
|
||||||
from pyrogram.types import Message, CallbackQuery, InlineKeyboardMarkup, InlineKeyboardButton
|
from pyrogram.types import Message, CallbackQuery, InlineKeyboardMarkup, InlineKeyboardButton
|
||||||
|
|
||||||
HELP_MSG_PRE = '<a href="https://git.io/JcbTD">PaimonBot</a> 0.3.8beta By Xtao-Labs\n\n' \
|
HELP_MSG_PRE = '<a href="https://gitlab.com/Xtao-Labs/Telegram_PaimonBot">PaimonBot</a> ' \
|
||||||
|
'0.4.0beta By Xtao-Labs\n\n' \
|
||||||
'🔅 以下是小派蒙我学会了的功能(部分):\n'
|
'🔅 以下是小派蒙我学会了的功能(部分):\n'
|
||||||
HELP_MSG = """① [武器/今日武器] 查看今日武器材料和武器
|
HELP_MSG = """① [武器/今日武器] 查看今日武器材料和武器
|
||||||
② [天赋/今日天赋] 查看今日天赋材料和角色
|
② [天赋/今日天赋] 查看今日天赋材料和角色
|
||||||
@ -36,7 +37,9 @@ HELP_MSG = """① [武器/今日武器] 查看今日武器材料和武器
|
|||||||
(17) [猜语音] 和群友一起玩猜语音小游戏吧!(群聊)
|
(17) [猜语音] 和群友一起玩猜语音小游戏吧!(群聊)
|
||||||
💠 <code>猜语音</code>
|
💠 <code>猜语音</code>
|
||||||
💠 <code>猜语音 无尽模式</code>
|
💠 <code>猜语音 无尽模式</code>
|
||||||
(18) [米游社/hoyolab] 米游社/hoyolab相关功能
|
(18) [怎么养 (角色名)] 输出角色适用武器&圣遗物
|
||||||
|
(19) [给谁用 (武器名)] 输出武器适用角色
|
||||||
|
(20) [米游社/hoyolab] 米游社/hoyolab相关功能
|
||||||
💠 <a href="https://telegra.ph/PaimonBot-02-18">点击查看</a>"""
|
💠 <a href="https://telegra.ph/PaimonBot-02-18">点击查看</a>"""
|
||||||
|
|
||||||
|
|
||||||
|
@ -14,3 +14,4 @@ apscheduler>=3.8.1
|
|||||||
wordcloud>=1.8.1
|
wordcloud>=1.8.1
|
||||||
numpy
|
numpy
|
||||||
sqlitedict
|
sqlitedict
|
||||||
|
openpyxl>=3.0.9
|
||||||
|
Loading…
Reference in New Issue
Block a user