✨ 米游社当前信息 (v0.4.1beta)
5
.gitignore
vendored
@ -142,7 +142,4 @@ temp/
|
|||||||
assets/icon/
|
assets/icon/
|
||||||
assets/data/list.json
|
assets/data/list.json
|
||||||
assets/voice/voice.json
|
assets/voice/voice.json
|
||||||
ID_DATA.db
|
*.db
|
||||||
ID_DATA_bak.db
|
|
||||||
ID_DATA_OR.db
|
|
||||||
ID_DATA_OR_bak.db
|
|
||||||
|
BIN
assets/bg/default4.jpg
Normal file
After Width: | Height: | Size: 486 KiB |
BIN
assets/bg/default5.jpg
Normal file
After Width: | Height: | Size: 171 KiB |
Before Width: | Height: | Size: 7.5 KiB After Width: | Height: | Size: 6.7 KiB |
BIN
assets/bg2/info_1.png
Normal file
After Width: | Height: | Size: 13 KiB |
BIN
assets/bg2/info_2.png
Normal file
After Width: | Height: | Size: 71 KiB |
BIN
assets/bg2/info_3.png
Normal file
After Width: | Height: | Size: 13 KiB |
BIN
assets/char_namecard/七七.png
Normal file
After Width: | Height: | Size: 108 KiB |
BIN
assets/char_namecard/丽莎.png
Normal file
After Width: | Height: | Size: 110 KiB |
BIN
assets/char_namecard/九条裟罗.png
Normal file
After Width: | Height: | Size: 164 KiB |
BIN
assets/char_namecard/云堇.png
Normal file
After Width: | Height: | Size: 92 KiB |
BIN
assets/char_namecard/五郎.png
Normal file
After Width: | Height: | Size: 190 KiB |
BIN
assets/char_namecard/优菈.png
Normal file
After Width: | Height: | Size: 188 KiB |
BIN
assets/char_namecard/八重神子.png
Normal file
After Width: | Height: | Size: 177 KiB |
BIN
assets/char_namecard/凝光.png
Normal file
After Width: | Height: | Size: 189 KiB |
BIN
assets/char_namecard/凯亚.png
Normal file
After Width: | Height: | Size: 167 KiB |
BIN
assets/char_namecard/刻晴.png
Normal file
After Width: | Height: | Size: 162 KiB |
BIN
assets/char_namecard/北斗.png
Normal file
After Width: | Height: | Size: 202 KiB |
BIN
assets/char_namecard/可莉.png
Normal file
After Width: | Height: | Size: 95 KiB |
BIN
assets/char_namecard/埃洛伊.png
Normal file
After Width: | Height: | Size: 166 KiB |
BIN
assets/char_namecard/安柏.png
Normal file
After Width: | Height: | Size: 113 KiB |
BIN
assets/char_namecard/宵宫.png
Normal file
After Width: | Height: | Size: 158 KiB |
BIN
assets/char_namecard/托马.png
Normal file
After Width: | Height: | Size: 136 KiB |
BIN
assets/char_namecard/早柚.png
Normal file
After Width: | Height: | Size: 138 KiB |
BIN
assets/char_namecard/枫原万叶.png
Normal file
After Width: | Height: | Size: 194 KiB |
BIN
assets/char_namecard/温迪.png
Normal file
After Width: | Height: | Size: 146 KiB |
BIN
assets/char_namecard/烟绯.png
Normal file
After Width: | Height: | Size: 203 KiB |
BIN
assets/char_namecard/珊瑚宫心海.png
Normal file
After Width: | Height: | Size: 254 KiB |
BIN
assets/char_namecard/班尼特.png
Normal file
After Width: | Height: | Size: 107 KiB |
BIN
assets/char_namecard/琴.png
Normal file
After Width: | Height: | Size: 219 KiB |
BIN
assets/char_namecard/甘雨.png
Normal file
After Width: | Height: | Size: 178 KiB |
BIN
assets/char_namecard/申鹤.png
Normal file
After Width: | Height: | Size: 144 KiB |
BIN
assets/char_namecard/砂糖.png
Normal file
After Width: | Height: | Size: 116 KiB |
BIN
assets/char_namecard/神里绫华.png
Normal file
After Width: | Height: | Size: 287 KiB |
BIN
assets/char_namecard/罗莎莉亚.png
Normal file
After Width: | Height: | Size: 125 KiB |
BIN
assets/char_namecard/胡桃.png
Normal file
After Width: | Height: | Size: 231 KiB |
BIN
assets/char_namecard/芭芭拉.png
Normal file
After Width: | Height: | Size: 133 KiB |
BIN
assets/char_namecard/荒泷一斗.png
Normal file
After Width: | Height: | Size: 226 KiB |
BIN
assets/char_namecard/莫娜.png
Normal file
After Width: | Height: | Size: 121 KiB |
BIN
assets/char_namecard/菲谢尔.png
Normal file
After Width: | Height: | Size: 94 KiB |
BIN
assets/char_namecard/行秋.png
Normal file
After Width: | Height: | Size: 122 KiB |
BIN
assets/char_namecard/诺艾尔.png
Normal file
After Width: | Height: | Size: 135 KiB |
BIN
assets/char_namecard/辛焱.png
Normal file
After Width: | Height: | Size: 187 KiB |
BIN
assets/char_namecard/达达利亚.png
Normal file
After Width: | Height: | Size: 109 KiB |
BIN
assets/char_namecard/迪卢克.png
Normal file
After Width: | Height: | Size: 149 KiB |
BIN
assets/char_namecard/迪奥娜.png
Normal file
After Width: | Height: | Size: 85 KiB |
BIN
assets/char_namecard/重云.png
Normal file
After Width: | Height: | Size: 135 KiB |
BIN
assets/char_namecard/钟离.png
Normal file
After Width: | Height: | Size: 137 KiB |
BIN
assets/char_namecard/阿贝多.png
Normal file
After Width: | Height: | Size: 158 KiB |
BIN
assets/char_namecard/雷泽.png
Normal file
After Width: | Height: | Size: 109 KiB |
BIN
assets/char_namecard/雷电将军.png
Normal file
After Width: | Height: | Size: 159 KiB |
BIN
assets/char_namecard/香菱.png
Normal file
After Width: | Height: | Size: 147 KiB |
BIN
assets/char_namecard/魈.png
Normal file
After Width: | Height: | Size: 184 KiB |
13
defs/db.py
@ -481,7 +481,6 @@ def cacheDB(uid, mode=1, mys=None):
|
|||||||
c.execute("UPDATE CookiesCache SET UID = ? WHERE MYSID=?", (uid, mys))
|
c.execute("UPDATE CookiesCache SET UID = ? WHERE MYSID=?", (uid, mys))
|
||||||
except:
|
except:
|
||||||
c.execute("UPDATE CookiesCache SET MYSID = ? WHERE UID=?", (mys, uid))
|
c.execute("UPDATE CookiesCache SET MYSID = ? WHERE UID=?", (mys, uid))
|
||||||
|
|
||||||
conn.commit()
|
conn.commit()
|
||||||
conn.close()
|
conn.close()
|
||||||
return use
|
return use
|
||||||
@ -585,14 +584,20 @@ async def GetInfo(Uid, ck, ServerID="cn_gf01"):
|
|||||||
ServerID = "cn_qd01"
|
ServerID = "cn_qd01"
|
||||||
try:
|
try:
|
||||||
req = await client.get(
|
req = await client.get(
|
||||||
url="https://api-takumi.mihoyo.com/game_record/app/genshin/api/index?role_id=" + Uid + "&server=" + ServerID,
|
url="https://api-takumi.mihoyo.com/game_record/app/genshin/api/index",
|
||||||
headers={
|
headers={
|
||||||
'DS': DSGet("role_id=" + Uid + "&server=" + ServerID),
|
'DS': DSGet("role_id=" + Uid + "&server=" + ServerID),
|
||||||
'x-rpc-app_version': mhyVersion,
|
'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',
|
'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',
|
'x-rpc-client_type': '5',
|
||||||
'Referer': 'https://webstatic.mihoyo.com/',
|
'Referer': 'https://webstatic.mihoyo.com/',
|
||||||
"Cookie": ck})
|
"Cookie": ck},
|
||||||
|
params={
|
||||||
|
"role_id": Uid,
|
||||||
|
"server": ServerID
|
||||||
|
}
|
||||||
|
)
|
||||||
data = json.loads(req.text)
|
data = json.loads(req.text)
|
||||||
# print(data)
|
# print(data)
|
||||||
return data
|
return data
|
||||||
|
393
defs/mys2.py
@ -1,3 +1,4 @@
|
|||||||
|
import json
|
||||||
import math
|
import math
|
||||||
import os
|
import os
|
||||||
import random
|
import random
|
||||||
@ -5,13 +6,17 @@ import sqlite3
|
|||||||
import threading
|
import threading
|
||||||
import time
|
import time
|
||||||
import urllib
|
import urllib
|
||||||
|
from io import BytesIO
|
||||||
|
from typing import Optional, Tuple
|
||||||
|
|
||||||
import numpy as np
|
import numpy as np
|
||||||
|
from httpx import get
|
||||||
from wordcloud import WordCloud
|
from wordcloud import WordCloud
|
||||||
from PIL import Image, ImageDraw, ImageFilter
|
from PIL import Image, ImageDraw, ImageFilter, ImageFont
|
||||||
from pyrogram.types import Message
|
from pyrogram.types import Message
|
||||||
|
|
||||||
from defs.db import GetAward, MysSign, GetSignInfo, GetSignList, GetDaily, cacheDB, GetMysInfo, \
|
from defs.db import GetAward, MysSign, GetSignInfo, GetSignList, GetDaily, cacheDB, GetMysInfo, \
|
||||||
errorDB, GetCharacter, GetInfo, GetSpiralAbyssInfo, MybSign
|
errorDB, GetCharacter, GetInfo, GetSpiralAbyssInfo, MybSign, get_spiral_abyss_info
|
||||||
from defs.event import ys_font
|
from defs.event import ys_font
|
||||||
|
|
||||||
WEAPON_PATH = os.path.join("assets", 'weapon')
|
WEAPON_PATH = os.path.join("assets", 'weapon')
|
||||||
@ -20,6 +25,7 @@ CHAR_DONE_PATH = os.path.join("assets", 'char_done')
|
|||||||
BG2_PATH = os.path.join("assets", "bg2")
|
BG2_PATH = os.path.join("assets", "bg2")
|
||||||
CHAR_PATH = os.path.join("assets", "characters")
|
CHAR_PATH = os.path.join("assets", "characters")
|
||||||
CHAR_IMG_PATH = os.path.join("assets", 'char_img')
|
CHAR_IMG_PATH = os.path.join("assets", 'char_img')
|
||||||
|
CHAR_NAMECARD_PATH = os.path.join("assets", 'char_namecard')
|
||||||
REL_PATH = os.path.join("assets", "reliquaries")
|
REL_PATH = os.path.join("assets", "reliquaries")
|
||||||
avatar_json = {
|
avatar_json = {
|
||||||
"Albedo": "阿贝多",
|
"Albedo": "阿贝多",
|
||||||
@ -95,6 +101,15 @@ UID:{}
|
|||||||
{}=============='''
|
{}=============='''
|
||||||
|
|
||||||
|
|
||||||
|
def genshin_font(size):
|
||||||
|
return ImageFont.truetype(f"assets{os.sep}fonts{os.sep}yuan_shen.ttf", size=size, encoding="utf-8")
|
||||||
|
|
||||||
|
|
||||||
|
def get_char_img_pic(url: str):
|
||||||
|
with open(os.path.join(CHAR_IMG_PATH, url.split(os.sep)[-1]), 'wb') as f:
|
||||||
|
f.write(get(url).content)
|
||||||
|
|
||||||
|
|
||||||
async def award(uid):
|
async def award(uid):
|
||||||
data = await GetAward(uid)
|
data = await GetAward(uid)
|
||||||
nickname = data['data']['nickname']
|
nickname = data['data']['nickname']
|
||||||
@ -962,3 +977,377 @@ async def draw_wordcloud(uid, message: Message, mode=2):
|
|||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
return f"temp{os.sep}cx.jpg"
|
return f"temp{os.sep}cx.jpg"
|
||||||
|
|
||||||
|
|
||||||
|
class GetCookies:
|
||||||
|
def __init__(self) -> None:
|
||||||
|
self.useable_cookies: Optional[str] = None
|
||||||
|
self.uid: Optional[str] = None
|
||||||
|
self.mode: Optional[int] = None
|
||||||
|
self.raw_abyss_data: Optional[json] = None
|
||||||
|
self.raw_data: Optional[json] = None
|
||||||
|
self.nickname: Optional[int] = None
|
||||||
|
self.schedule_type: Optional[str] = None
|
||||||
|
|
||||||
|
async def get_useable_cookies(self, uid: str, mode: int = 2, schedule_type: str = "1"):
|
||||||
|
self.uid = uid
|
||||||
|
self.schedule_type = schedule_type
|
||||||
|
while True:
|
||||||
|
self.useable_cookies = cacheDB(uid, mode - 1)
|
||||||
|
if self.useable_cookies == '':
|
||||||
|
return "绑定记录不存在。"
|
||||||
|
elif self.useable_cookies == "没有可以使用的Cookies!":
|
||||||
|
return "没有可以使用的Cookies!"
|
||||||
|
if mode == 3:
|
||||||
|
await self.get_mihoyo_bbs_data()
|
||||||
|
else:
|
||||||
|
await self.get_uid_data()
|
||||||
|
|
||||||
|
msg = await self.check_cookies_useable()
|
||||||
|
if isinstance(msg, str):
|
||||||
|
return msg
|
||||||
|
elif isinstance(msg, bool):
|
||||||
|
if msg:
|
||||||
|
return True
|
||||||
|
|
||||||
|
async def get_mihoyo_bbs_data(self):
|
||||||
|
mys_data = await GetMysInfo(self.uid, self.useable_cookies)
|
||||||
|
for i in mys_data['data']['list']:
|
||||||
|
if i['game_id'] != 2:
|
||||||
|
mys_data['data']['list'].remove(i)
|
||||||
|
self.uid = mys_data['data']['list'][0]['game_role_id']
|
||||||
|
self.nickname = mys_data['data']['list'][0]['nickname']
|
||||||
|
self.raw_data = await GetInfo(self.uid, self.useable_cookies)
|
||||||
|
self.raw_abyss_data = await get_spiral_abyss_info(self.uid, self.useable_cookies, self.schedule_type)
|
||||||
|
|
||||||
|
async def get_uid_data(self):
|
||||||
|
self.raw_abyss_data = await get_spiral_abyss_info(self.uid, self.useable_cookies, self.schedule_type)
|
||||||
|
self.raw_data = await GetInfo(self.uid, self.useable_cookies)
|
||||||
|
|
||||||
|
async def check_cookies_useable(self):
|
||||||
|
if self.raw_data:
|
||||||
|
if self.raw_data["retcode"] != 0:
|
||||||
|
if self.raw_data["retcode"] == 10001:
|
||||||
|
errorDB(self.useable_cookies, "error")
|
||||||
|
return False
|
||||||
|
elif self.raw_data["retcode"] == 10101:
|
||||||
|
errorDB(self.useable_cookies, "limit30")
|
||||||
|
return False
|
||||||
|
elif self.raw_data["retcode"] == 10102:
|
||||||
|
return "当前查询id已经设置了隐私,无法查询!"
|
||||||
|
else:
|
||||||
|
return (
|
||||||
|
"Api报错,返回内容为:\r\n"
|
||||||
|
+ str(self.raw_data) + "\r\n出现这种情况可能的UID输入错误 or 不存在"
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
return "没有可以使用的Cookies!"
|
||||||
|
|
||||||
|
|
||||||
|
class CustomizeImage:
|
||||||
|
def __init__(self, image: str, based_w: int, based_h: int) -> None:
|
||||||
|
|
||||||
|
self.bg_img = self.get_image(image, based_w, based_h)
|
||||||
|
self.bg_color = self.get_bg_color(self.bg_img)
|
||||||
|
self.text_color = self.get_text_color(self.bg_color)
|
||||||
|
self.highlight_color = self.get_highlight_color(self.bg_color)
|
||||||
|
self.char_color = self.get_char_color(self.bg_color)
|
||||||
|
self.bg_detail_color = self.get_bg_detail_color(self.bg_color)
|
||||||
|
self.char_high_color = self.get_char_high_color(self.bg_color)
|
||||||
|
|
||||||
|
def get_image(self, image: str, based_w: int, based_h: int) -> Image:
|
||||||
|
# 获取背景图片
|
||||||
|
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_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))
|
||||||
|
|
||||||
|
return bg_img
|
||||||
|
|
||||||
|
def get_bg_color(self, edit_bg: Image) -> Tuple[int, int, int]:
|
||||||
|
# 获取背景主色
|
||||||
|
color = 8
|
||||||
|
q = edit_bg.quantize(colors=color, method=2)
|
||||||
|
bg_color = None
|
||||||
|
based_light = 195
|
||||||
|
temp = 9999
|
||||||
|
for i in range(0, color):
|
||||||
|
bg = tuple(q.getpalette()[i * 3:(i * 3) + 3])
|
||||||
|
light_value = bg[0] * 0.3 + bg[1] * 0.6 + bg[2] * 0.1
|
||||||
|
if abs(light_value - based_light) < temp:
|
||||||
|
bg_color = bg
|
||||||
|
temp = abs(light_value - based_light)
|
||||||
|
# if max(*bg) < 240 and min(*bg) > 20:
|
||||||
|
# bg_color = bg
|
||||||
|
return bg_color
|
||||||
|
|
||||||
|
def get_text_color(self, bg_color: Tuple[int, int, int]) -> Tuple[int, int, int]:
|
||||||
|
# 通过背景主色(bg_color)确定文字主色
|
||||||
|
r = 125
|
||||||
|
if max(*bg_color) > 255 - r:
|
||||||
|
r *= -1
|
||||||
|
text_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))
|
||||||
|
return text_color
|
||||||
|
|
||||||
|
def get_char_color(self, bg_color: Tuple[int, int, int]) -> Tuple[int, int, int]:
|
||||||
|
r = 140
|
||||||
|
if max(*bg_color) > 255 - r:
|
||||||
|
r *= -1
|
||||||
|
char_color = (math.floor(bg_color[0] + 5 if bg_color[0] + r <= 255 else 255),
|
||||||
|
math.floor(bg_color[1] + 5 if bg_color[1] + r <= 255 else 255),
|
||||||
|
math.floor(bg_color[2] + 5 if bg_color[2] + r <= 255 else 255))
|
||||||
|
return char_color
|
||||||
|
|
||||||
|
def get_char_high_color(self, bg_color: Tuple[int, int, int]) -> Tuple[int, int, int]:
|
||||||
|
r = 140
|
||||||
|
d = 20
|
||||||
|
if max(*bg_color) > 255 - r:
|
||||||
|
r *= -1
|
||||||
|
char_color = (math.floor(bg_color[0] + d if bg_color[0] + r <= 255 else 255),
|
||||||
|
math.floor(bg_color[1] + d if bg_color[1] + r <= 255 else 255),
|
||||||
|
math.floor(bg_color[2] + d if bg_color[2] + r <= 255 else 255))
|
||||||
|
return char_color
|
||||||
|
|
||||||
|
def get_bg_detail_color(self, bg_color: Tuple[int, int, int]) -> Tuple[int, int, int]:
|
||||||
|
r = 140
|
||||||
|
if max(*bg_color) > 255 - r:
|
||||||
|
r *= -1
|
||||||
|
bg_detail_color = (math.floor(bg_color[0] - 20 if bg_color[0] + r <= 255 else 255),
|
||||||
|
math.floor(bg_color[1] - 20 if bg_color[1] + r <= 255 else 255),
|
||||||
|
math.floor(bg_color[2] - 20 if bg_color[2] + r <= 255 else 255))
|
||||||
|
return bg_detail_color
|
||||||
|
|
||||||
|
def get_highlight_color(self, color: Tuple[int, int, int]) -> Tuple[int, int, int]:
|
||||||
|
red_color = color[0]
|
||||||
|
green_color = color[1]
|
||||||
|
blue_color = color[2]
|
||||||
|
|
||||||
|
highlight_color = {}
|
||||||
|
highlight_color["red"] = red_color - 127 if red_color > 127 else 127
|
||||||
|
highlight_color["green"] = green_color - 127 if green_color > 127 else 127
|
||||||
|
highlight_color["blue"] = blue_color - 127 if blue_color > 127 else 127
|
||||||
|
|
||||||
|
max_color = max(highlight_color.values())
|
||||||
|
name = "red"
|
||||||
|
for _highlight_color in highlight_color:
|
||||||
|
if highlight_color[_highlight_color] == max_color:
|
||||||
|
name = str(_highlight_color)
|
||||||
|
|
||||||
|
if name == "red":
|
||||||
|
return red_color, highlight_color["green"], highlight_color["blue"]
|
||||||
|
elif name == "green":
|
||||||
|
return highlight_color["red"], green_color, highlight_color["blue"]
|
||||||
|
elif name == "blue":
|
||||||
|
return highlight_color["red"], highlight_color["green"], blue_color
|
||||||
|
else:
|
||||||
|
return 0, 0, 0 # Error
|
||||||
|
|
||||||
|
|
||||||
|
async def draw_info_pic(uid: str, image=None) -> str:
|
||||||
|
def seconds2hours(seconds: int) -> str:
|
||||||
|
m, s = divmod(int(seconds), 60)
|
||||||
|
h, m = divmod(m, 60)
|
||||||
|
return "%02d:%02d:%02d" % (h, m, s)
|
||||||
|
|
||||||
|
# 获取Cookies
|
||||||
|
data_def = GetCookies()
|
||||||
|
retcode = await data_def.get_useable_cookies(uid)
|
||||||
|
if not retcode:
|
||||||
|
return retcode
|
||||||
|
raw_data = data_def.raw_data
|
||||||
|
char_data = raw_data["data"]["avatars"]
|
||||||
|
# 获取数据
|
||||||
|
award_data = await GetAward(uid)
|
||||||
|
daily_data = await GetDaily(uid)
|
||||||
|
daily_data = daily_data["data"]
|
||||||
|
nickname = award_data['data']['nickname']
|
||||||
|
|
||||||
|
# 获取背景图片各项参数
|
||||||
|
based_w = 900
|
||||||
|
based_h = 1380
|
||||||
|
image_def = CustomizeImage(image, based_w, based_h)
|
||||||
|
bg_img = image_def.bg_img
|
||||||
|
bg_color = image_def.bg_color
|
||||||
|
text_color = image_def.text_color
|
||||||
|
highlight_color = image_def.highlight_color
|
||||||
|
char_color = image_def.char_color
|
||||||
|
|
||||||
|
# 确定texture2D路径
|
||||||
|
info1_path = os.path.join(BG2_PATH, "info_1.png")
|
||||||
|
info2_path = os.path.join(BG2_PATH, "info_2.png")
|
||||||
|
info3_path = os.path.join(BG2_PATH, "info_3.png")
|
||||||
|
|
||||||
|
avatar_bg_path = os.path.join(BG2_PATH, "avatar_bg.png")
|
||||||
|
avatar_fg_path = os.path.join(BG2_PATH, "avatar_fg.png")
|
||||||
|
|
||||||
|
all_mask_path = os.path.join(BG2_PATH, "All_Mask.png")
|
||||||
|
|
||||||
|
# 转换遮罩的颜色、大小匹配,并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)
|
||||||
|
|
||||||
|
# 操作图片
|
||||||
|
info1 = Image.open(info1_path)
|
||||||
|
info2 = Image.open(info2_path)
|
||||||
|
info3 = Image.open(info3_path)
|
||||||
|
avatar_bg = Image.open(avatar_bg_path)
|
||||||
|
avatar_fg = Image.open(avatar_fg_path)
|
||||||
|
|
||||||
|
avatar_bg_color = Image.new("RGBA", (316, 100), bg_color)
|
||||||
|
bg_img.paste(avatar_bg_color, (113, 98), avatar_bg)
|
||||||
|
bg_img.paste(avatar_fg, (114, 95), avatar_fg)
|
||||||
|
|
||||||
|
info1_color = Image.new("RGBA", (900, 1300), bg_color)
|
||||||
|
bg_img.paste(info1_color, (0, 0), info1)
|
||||||
|
|
||||||
|
info2_color = Image.new("RGBA", (900, 1300), text_color)
|
||||||
|
bg_img.paste(info2_color, (0, 0), info2)
|
||||||
|
|
||||||
|
bg_img.paste(info3, (0, 0), info3)
|
||||||
|
|
||||||
|
text_draw = ImageDraw.Draw(bg_img)
|
||||||
|
|
||||||
|
# 用户信息
|
||||||
|
text_draw.text((220, 137), f"{nickname}", text_color, genshin_font(32), anchor="lm")
|
||||||
|
text_draw.text((235, 170), 'UID ' + f"{uid}", text_color, genshin_font(14), anchor="lm")
|
||||||
|
|
||||||
|
# 本日原石/摩拉
|
||||||
|
text_draw.text((675, 148),
|
||||||
|
f"{award_data['data']['day_data']['current_primogems']}/{award_data['data']['day_data']['last_primogems']}",
|
||||||
|
text_color, genshin_font(28), anchor="lm")
|
||||||
|
text_draw.text((675, 212),
|
||||||
|
f"{award_data['data']['day_data']['current_mora']}\n{award_data['data']['day_data']['last_mora']}",
|
||||||
|
text_color, genshin_font(28), anchor="lm")
|
||||||
|
|
||||||
|
# 本月/上月原石
|
||||||
|
text_draw.text((722, 287), f"{award_data['data']['month_data']['current_primogems']}", text_color, genshin_font(21),
|
||||||
|
anchor="lm")
|
||||||
|
text_draw.text((722, 323), f"{award_data['data']['month_data']['last_primogems']}", text_color, genshin_font(21),
|
||||||
|
anchor="lm")
|
||||||
|
|
||||||
|
# 本月/上月摩拉
|
||||||
|
text_draw.text((722, 359), f"{award_data['data']['month_data']['current_mora']}", text_color, genshin_font(21),
|
||||||
|
anchor="lm")
|
||||||
|
text_draw.text((722, 395), f"{award_data['data']['month_data']['last_mora']}", text_color, genshin_font(21),
|
||||||
|
anchor="lm")
|
||||||
|
|
||||||
|
# 收入比例
|
||||||
|
for index, i in enumerate(award_data['data']['month_data']['group_by']):
|
||||||
|
text_draw.text((681, 445 + index * 32), f"{str(i['num'])}({str(i['percent'])}%)", text_color, genshin_font(21),
|
||||||
|
anchor="lm")
|
||||||
|
|
||||||
|
# 基本四项
|
||||||
|
text_draw.text((390, 314), f"{daily_data['current_resin']}/{daily_data['max_resin']}", text_color, genshin_font(26),
|
||||||
|
anchor="lm")
|
||||||
|
text_draw.text((390, 408), f'{daily_data["current_home_coin"]}/{daily_data["max_home_coin"]}', text_color,
|
||||||
|
genshin_font(26), anchor="lm")
|
||||||
|
text_draw.text((390, 503), f"{daily_data['finished_task_num']}/{daily_data['total_task_num']}", text_color,
|
||||||
|
genshin_font(26), anchor="lm")
|
||||||
|
text_draw.text((390, 597),
|
||||||
|
f"{str(daily_data['resin_discount_num_limit'] - daily_data['remain_resin_discount_num'])}/{daily_data['resin_discount_num_limit']}",
|
||||||
|
text_color, genshin_font(26), anchor="lm")
|
||||||
|
|
||||||
|
# 树脂恢复时间计算
|
||||||
|
resin_recovery_time = seconds2hours(
|
||||||
|
daily_data['resin_recovery_time'])
|
||||||
|
next_resin_rec_time = seconds2hours(
|
||||||
|
8 * 60 - ((daily_data['max_resin'] - daily_data['current_resin']) * 8 * 60 - int(
|
||||||
|
daily_data['resin_recovery_time'])))
|
||||||
|
text_draw.text((268, 305), f" {next_resin_rec_time}", text_color, genshin_font(18), anchor="lm")
|
||||||
|
|
||||||
|
text_draw.text((170, 331), f"预计 后全部恢复", text_color, genshin_font(18), anchor="lm")
|
||||||
|
text_draw.text((208, 331), f"{resin_recovery_time}", highlight_color, genshin_font(18), anchor="lm")
|
||||||
|
|
||||||
|
# 洞天宝钱时间计算
|
||||||
|
coin_rec_time = seconds2hours(int(daily_data["home_coin_recovery_time"]))
|
||||||
|
|
||||||
|
if daily_data["home_coin_recovery_time"] == "0":
|
||||||
|
text_draw.text((170, 425), f"已满", text_color, genshin_font(18), anchor="lm")
|
||||||
|
else:
|
||||||
|
coin_add_speed = math.ceil((daily_data["max_home_coin"] - daily_data["current_home_coin"]) / (
|
||||||
|
int(daily_data["home_coin_recovery_time"]) / 60 / 60))
|
||||||
|
text_draw.text((270, 399), f"约{coin_add_speed}/h", text_color, genshin_font(18), anchor="lm")
|
||||||
|
text_draw.text((170, 425), f"预计 后达到上限", text_color, genshin_font(18), anchor="lm")
|
||||||
|
text_draw.text((208, 425), f"{coin_rec_time}", highlight_color, genshin_font(18), anchor="lm")
|
||||||
|
|
||||||
|
if daily_data['is_extra_task_reward_received']:
|
||||||
|
daily_task_status = "「每日委托」奖励已领取"
|
||||||
|
else:
|
||||||
|
daily_task_status = "「每日委托」奖励未领取"
|
||||||
|
|
||||||
|
# 详细信息
|
||||||
|
text_draw.text((170, 518), f"{daily_task_status}", text_color, genshin_font(18), anchor="lm")
|
||||||
|
text_draw.text((170, 614), f"本周剩余消耗减半次数", text_color, genshin_font(18), anchor="lm")
|
||||||
|
|
||||||
|
# 派遣图片准备
|
||||||
|
char_bg_path = os.path.join(BG2_PATH, "char_bg.png")
|
||||||
|
|
||||||
|
char_bg = Image.open(char_bg_path)
|
||||||
|
charset_mask = Image.new("RGBA", (900, 130), char_color)
|
||||||
|
|
||||||
|
# 派遣
|
||||||
|
for index, i in enumerate(daily_data["expeditions"]):
|
||||||
|
for j in char_data:
|
||||||
|
if i["avatar_side_icon"].split("_")[-1] == j["image"].split("_")[-1]:
|
||||||
|
name = j["name"]
|
||||||
|
if not os.path.exists(
|
||||||
|
os.path.join(CHAR_IMG_PATH, f"UI_AvatarIcon_{i['avatar_side_icon'].split('_')[-1][:-4]}@2x.png")):
|
||||||
|
get_char_img_pic(
|
||||||
|
f"https://upload-bbs.mihoyo.com/game_record/genshin/character_image/UI_AvatarIcon_{i['avatar_side_icon'].split('_')[-1][:-4]}@2x.png")
|
||||||
|
# char_stand_img = os.path.join(CHAR_IMG_PATH, f"UI_AvatarIcon_{i['avatar_side_icon'].split('_')[-1][:-4]}@2x.png")
|
||||||
|
# char_stand = Image.open(char_stand_img)
|
||||||
|
# char_stand_mask = Image.open(os.path.join(TEXT_PATH, "stand_mask.png"))
|
||||||
|
|
||||||
|
# charpic_temp = Image.new("RGBA", (900, 130))
|
||||||
|
# charpic_temp.paste(char_stand, (395, -99), char_stand_mask)
|
||||||
|
charpic = Image.new("RGBA", (900, 130))
|
||||||
|
char_icon = Image.open(BytesIO(get(i['avatar_side_icon']).content))
|
||||||
|
|
||||||
|
char_namecard_img = Image.open(os.path.join(CHAR_NAMECARD_PATH, str(name + ".png")))
|
||||||
|
char_namecard_img = char_namecard_img.resize((591, 81), Image.ANTIALIAS)
|
||||||
|
char_namecard_img.putalpha(char_namecard_img.getchannel('A').point(lambda i: i * 0.8 if i > 0 else 0))
|
||||||
|
|
||||||
|
char_icon_scale = char_icon.resize((140, 140), Image.ANTIALIAS)
|
||||||
|
charpic.paste(charset_mask, (0, 0), char_bg)
|
||||||
|
charpic.paste(char_icon_scale, (63, -26), char_icon_scale)
|
||||||
|
charpic.paste(char_namecard_img, (247, 24), char_namecard_img)
|
||||||
|
|
||||||
|
charpic_draw = ImageDraw.Draw(charpic)
|
||||||
|
|
||||||
|
if i['status'] == 'Finished':
|
||||||
|
charpic_draw.text((200, 65), f"探索完成", text_color, genshin_font(24), anchor="lm")
|
||||||
|
else:
|
||||||
|
remained_timed: str = seconds2hours(i['remained_time'])
|
||||||
|
charpic_draw.text((200, 65), f"剩余时间 {remained_timed}", text_color, genshin_font(24), anchor="lm")
|
||||||
|
|
||||||
|
bg_img.paste(charpic, (-15, 748 + 115 * index), charpic)
|
||||||
|
|
||||||
|
end_pic = Image.open(os.path.join(BG2_PATH, "abyss_3.png"))
|
||||||
|
bg_img.paste(end_pic, (0, 1340), end_pic)
|
||||||
|
|
||||||
|
# 转换之后发送
|
||||||
|
bg_img = bg_img.convert('RGB')
|
||||||
|
bg_img.save(f"temp{os.sep}info.jpg", format='JPEG', subsampling=0, quality=90)
|
||||||
|
return f"temp{os.sep}info.jpg"
|
||||||
|
@ -10,7 +10,7 @@ from pyrogram.types import Message
|
|||||||
|
|
||||||
from defs.db import deal_ck, selectDB, OpenPush, CheckDB, connectDB, deletecache
|
from defs.db import deal_ck, selectDB, OpenPush, CheckDB, connectDB, deletecache
|
||||||
from defs.event import generate_event
|
from defs.event import generate_event
|
||||||
from defs.mys2 import award, sign, daily, draw_pic, draw_wordcloud
|
from defs.mys2 import award, sign, daily, draw_pic, draw_wordcloud, draw_info_pic
|
||||||
from defs.mihoyo import draw_pic as draw_pic_2
|
from defs.mihoyo import draw_pic as draw_pic_2
|
||||||
|
|
||||||
from ci import scheduler, app, admin_id
|
from ci import scheduler, app, admin_id
|
||||||
@ -183,6 +183,19 @@ async def mys2_qun_msg(client: Client, message: Message):
|
|||||||
traceback.print_exc()
|
traceback.print_exc()
|
||||||
im = "没有找到绑定信息。"
|
im = "没有找到绑定信息。"
|
||||||
await message.reply(im)
|
await message.reply(im)
|
||||||
|
elif "当前信息" in text:
|
||||||
|
try:
|
||||||
|
uid = await selectDB(message.from_user.id, mode="uid")
|
||||||
|
uid = uid[0]
|
||||||
|
im = await draw_info_pic(uid)
|
||||||
|
if not im:
|
||||||
|
await message.reply("未查找到该用户的当前信息。")
|
||||||
|
else:
|
||||||
|
await message.reply_photo(im)
|
||||||
|
except Exception as e:
|
||||||
|
traceback.print_exc()
|
||||||
|
im = "没有找到绑定信息。"
|
||||||
|
await message.reply(im)
|
||||||
elif "绑定uid" in text:
|
elif "绑定uid" in text:
|
||||||
uid = text.replace("绑定uid", "") # str
|
uid = text.replace("绑定uid", "") # str
|
||||||
if is_chinese(uid):
|
if is_chinese(uid):
|
||||||
|
@ -3,7 +3,7 @@ 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://gitlab.com/Xtao-Labs/Telegram_PaimonBot">PaimonBot</a> ' \
|
HELP_MSG_PRE = '<a href="https://gitlab.com/Xtao-Labs/Telegram_PaimonBot">PaimonBot</a> ' \
|
||||||
'0.4.0beta By Xtao-Labs\n\n' \
|
'0.4.1beta By Xtao-Labs\n\n' \
|
||||||
'🔅 以下是小派蒙我学会了的功能(部分):\n'
|
'🔅 以下是小派蒙我学会了的功能(部分):\n'
|
||||||
HELP_MSG = """① [武器/今日武器] 查看今日武器材料和武器
|
HELP_MSG = """① [武器/今日武器] 查看今日武器材料和武器
|
||||||
② [天赋/今日天赋] 查看今日天赋材料和角色
|
② [天赋/今日天赋] 查看今日天赋材料和角色
|
||||||
|