新增:若干功能
25
README.md
@ -8,7 +8,11 @@
|
||||
|
||||
再次提醒:**Cookies是重要信息,请不要随意泄露!!!**
|
||||
|
||||
示例: 
|
||||
示例:
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
- [安装(HoshinoBot)](#安装(HoshinoBot))
|
||||
- [更新记录](#更新记录)
|
||||
@ -48,6 +52,20 @@ $ pip3 install -r requirements.txt
|
||||
|
||||
**(作者已经转用NoneBot2,Hoshino的更新可能未经测试,有bug及时提Issues!)**
|
||||
|
||||
#### 2021-12-20
|
||||
|
||||
新增:8角色查询UI,全角色查询UI将会随背景图片改变而改变主题色。
|
||||
|
||||
新增:`角色xx<数字>`命令,例如`角色钟离84`,可以查看84级钟离基本属性。
|
||||
|
||||
新增:`角色xx`命令的类型匹配,例如`角色长柄武器`,可以查看所有长柄武器的角色,例如`角色火`,`角色火元素伤害加成`,`角色琉璃袋`,`角色燃愿玛瑙`等等……
|
||||
|
||||
新增:`活动列表`命令,第一次使用可能输出时间略久,需等待一段时间。
|
||||
|
||||
新增:`御神签`命令,随机抽签。
|
||||
|
||||
修复:若干bug
|
||||
|
||||
#### 2021-12-04
|
||||
|
||||
修复:`查询词云`功能失效的问题。
|
||||
@ -212,7 +230,8 @@ $ pip3 install -r requirements.txt
|
||||
| mys | | 角色信息(带武器信息,冒险等级) | mys123456 | 米游社通行证 |
|
||||
| mys | (上期)深渊 | 获取角色深渊总览(层数为最后一层) | mys123456深渊 | 米游社通行证 |
|
||||
| mys | (上期)深渊9/10/11/12 | 获取角色深渊某一层数据 | mys123456深渊12 | 米游社通行证 |
|
||||
| UID | | 获取角色信息一览(不带武器信息) | UID123456789 | 旧版本,比例更和谐 |
|
||||
| 活动列表 | | 输出活动列表 | 活动列表 | |
|
||||
| 御神签 | | 抽一张御神签 | 御神签 | |
|
||||
| 绑定uid | | 当前qq号关联绑定uid | 绑定uid123456789 | 查询前缀前置条件 |
|
||||
| 绑定mys | | 当前qq号关联绑定米游社通行证 | 绑定mys12345678 | 查询前缀前置条件 |
|
||||
| 查询 | | 查询当前绑定角色信息一览 | 查询 | **必须**绑定过mys/uid |
|
||||
@ -236,6 +255,8 @@ $ pip3 install -r requirements.txt
|
||||
| 武器 | | 查询武器信息 | 武器天空之卷 | |
|
||||
| 命座\d | | 查询角色命座信息 | 命座6可莉 | |
|
||||
| 角色 | | 查询角色简略信息 | 角色可莉 | |
|
||||
| 角色 | \d | 查询角色某个等级的属性 | 角色可莉64 | |
|
||||
| 角色 | <某种类型> | 匹配一整类角色 | 角色燃愿玛瑙 | |
|
||||
| 查询词云 | | 查询绑定角色的词云 | 查询词云 | 必须绑定过UID/MYSID |
|
||||
|
||||
### 深渊查询:
|
||||
|
128
__init__.py
@ -1,12 +1,12 @@
|
||||
from .getImg import draw_pic,draw_abyss_pic,draw_abyss0_pic,draw_wordcloud
|
||||
from .getImg import draw_pic,draw_abyss_pic,draw_abyss0_pic,draw_wordcloud,draw_event_pic
|
||||
from .getDB import (CheckDB, GetAward, GetCharInfo, GetDaily, GetMysInfo,
|
||||
GetSignInfo, GetSignList, GetWeaponInfo, MysSign, OpenPush,
|
||||
connectDB, cookiesDB, deletecache, selectDB)
|
||||
connectDB, cookiesDB, deletecache, selectDB, get_alots)
|
||||
from nonebot import *
|
||||
from hoshino import Service,R,priv,util
|
||||
from hoshino.typing import MessageSegment,CQEvent, HoshinoBot
|
||||
|
||||
import requests,random,os,json,re,time,datetime,string,base64
|
||||
import requests,random,os,json,re,time,datetime,string,base64,math
|
||||
|
||||
import threading
|
||||
import hoshino
|
||||
@ -112,6 +112,31 @@ char_info_im = '''{}
|
||||
【cv】:{}
|
||||
【介绍】:{}'''
|
||||
|
||||
@sv.on_fullmatch('活动列表')
|
||||
async def _(bot:HoshinoBot, ev: CQEvent):
|
||||
img_path = os.path.join(FILE2_PATH,"event.jpg")
|
||||
while(1):
|
||||
if os.path.exists(img_path):
|
||||
im = f'[CQ:image,file=file://{img_path}]'
|
||||
break
|
||||
else:
|
||||
await draw_event_pic()
|
||||
await bot.send(ev,im)
|
||||
|
||||
@sv.on_fullmatch('御神签')
|
||||
async def _(bot:HoshinoBot, ev: CQEvent):
|
||||
qid = ev.sender["user_id"]
|
||||
raw_data = await get_alots(qid)
|
||||
im = base64.b64decode(raw_data).decode("utf-8")
|
||||
await bot.send(ev,im)
|
||||
|
||||
@sv.on_prefix('材料')
|
||||
async def _(bot:HoshinoBot, ev: CQEvent):
|
||||
message = ev.message.extract_plain_text()
|
||||
message = message.replace(' ', "")
|
||||
im = await char_wiki(message,extra="cost")
|
||||
await bot.send(ev,im)
|
||||
|
||||
@sv.on_prefix('武器')
|
||||
async def _(bot:HoshinoBot, ev: CQEvent):
|
||||
message = ev.message.extract_plain_text()
|
||||
@ -121,8 +146,14 @@ async def _(bot:HoshinoBot, ev: CQEvent):
|
||||
@sv.on_prefix('角色')
|
||||
async def _(bot:HoshinoBot, ev: CQEvent):
|
||||
message = ev.message.extract_plain_text()
|
||||
im = await char_wiki(message)
|
||||
await bot.send(ev,im,at_sender=True)
|
||||
message = message.replace(' ', "")
|
||||
name = ''.join(re.findall('[\u4e00-\u9fa5]', message))
|
||||
level = re.findall(r"[0-9]+", message)
|
||||
if len(level) == 1:
|
||||
im = await char_wiki(name,extra="stats",num=level[0])
|
||||
else:
|
||||
im = await char_wiki(name)
|
||||
await bot.send(ev,im)
|
||||
|
||||
@sv.on_prefix('命座')
|
||||
async def _(bot:HoshinoBot, ev: CQEvent):
|
||||
@ -498,20 +529,6 @@ async def _(bot:HoshinoBot, ev: CQEvent):
|
||||
except:
|
||||
await bot.send(ev,'输入错误!')
|
||||
|
||||
#群聊内 查询uid 的命令(旧版),不输出武器信息
|
||||
@sv.on_prefix('UID')
|
||||
async def _(bot:HoshinoBot, ev: CQEvent):
|
||||
image = re.search(r"\[CQ:image,file=(.*),url=(.*)\]", str(ev.message))
|
||||
message = ev.message.extract_plain_text()
|
||||
uid = re.findall(r"\d+", message)[0] # str
|
||||
try:
|
||||
im = await draw_pic(uid,ev.sender['nickname'],image,1)
|
||||
await bot.send(ev, im, at_sender=True)
|
||||
except:
|
||||
await bot.send(ev,'输入错误!')
|
||||
|
||||
|
||||
|
||||
#签到函数
|
||||
async def sign(uid):
|
||||
try:
|
||||
@ -643,21 +660,68 @@ async def weapon_wiki(name):
|
||||
sub, effect)
|
||||
return im
|
||||
|
||||
async def char_wiki(name,mode = 0,num = 0):
|
||||
data = await GetCharInfo(name,mode)
|
||||
async def char_wiki(name, mode=0, num="", extra=""):
|
||||
data = await GetCharInfo(name, mode)
|
||||
if mode == 0:
|
||||
name = data['title'] + ' — ' + data['name']
|
||||
star = data['rarity']
|
||||
type = data["weapontype"]
|
||||
element = data['element']
|
||||
up_val = data['substat']
|
||||
bdday = data['birthday']
|
||||
polar = data['constellation']
|
||||
cv = data['cv']['chinese']
|
||||
info = data['description']
|
||||
im = char_info_im.format(name,star,type,element,up_val,bdday,polar,cv,info)
|
||||
if isinstance(data,str):
|
||||
raw_data = data.replace("[","").replace("\n","").replace("]","").replace(" ","").replace("'","").split(',')
|
||||
if data.replace("\n","").replace(" ","") == "undefined":
|
||||
im = "不存在该角色或类型。"
|
||||
else:
|
||||
im = ','.join(raw_data)
|
||||
else:
|
||||
if extra == "cost":
|
||||
talent_data = await GetCharInfo(name, 1)
|
||||
|
||||
im = "【天赋材料(一份)】\n{}\n【突破材料】\n{}"
|
||||
im1 = ""
|
||||
im2 = ""
|
||||
|
||||
talent_temp = {}
|
||||
talent_cost = talent_data["costs"]
|
||||
for i in talent_cost.values():
|
||||
for j in i:
|
||||
if j["name"] not in talent_temp:
|
||||
talent_temp[j["name"]] = j["count"]
|
||||
else:
|
||||
talent_temp[j["name"]] = talent_temp[j["name"]] + j["count"]
|
||||
for k in talent_temp:
|
||||
im1 = im1 + k + ":" + str(talent_temp[k]) + "\n"
|
||||
|
||||
temp = {}
|
||||
cost = data["costs"]
|
||||
for i in range(1,7):
|
||||
for j in cost["ascend{}".format(i)]:
|
||||
if j["name"] not in temp:
|
||||
temp[j["name"]] = j["count"]
|
||||
else:
|
||||
temp[j["name"]] = temp[j["name"]] + j["count"]
|
||||
|
||||
for k in temp:
|
||||
im2 = im2 + k + ":" + str(temp[k]) + "\n"
|
||||
|
||||
im = im.format(im1,im2)
|
||||
|
||||
elif extra == "stats":
|
||||
data2 = await GetCharInfo(name, mode, num)
|
||||
im = (name + "\n等级:" + str(data2["level"]) + "\n血量:" + str(math.floor(data2["hp"])) +
|
||||
"\n攻击力:" + str(math.floor(data2["attack"])) + "\n防御力:" + str(math.floor(data2["defense"])) +
|
||||
"\n" + data["substat"] + ":" + '%.1f%%' % (data2["specialized"] * 100))
|
||||
else:
|
||||
name = data['title'] + ' — ' + data['name']
|
||||
star = data['rarity']
|
||||
type = data["weapontype"]
|
||||
element = data['element']
|
||||
up_val = data['substat']
|
||||
bdday = data['birthday']
|
||||
polar = data['constellation']
|
||||
cv = data['cv']['chinese']
|
||||
info = data['description']
|
||||
im = char_info_im.format(
|
||||
name, star, type, element, up_val, bdday, polar, cv, info)
|
||||
elif mode == 1:
|
||||
im = '暂不支持'
|
||||
elif mode == 2:
|
||||
im = data["c{}".format(num)]['name'] + ":" + data["c{}".format(num)]['effect']
|
||||
im = "【" + data["c{}".format(num)]['name'] + "】" + ":" + \
|
||||
"\n" + data["c{}".format(num)]['effect'].replace("*", "")
|
||||
return im
|
||||
|
111
getDB.py
@ -2,6 +2,7 @@ import sqlite3
|
||||
import sys
|
||||
|
||||
from httpx import AsyncClient
|
||||
from shutil import copyfile
|
||||
|
||||
from nonebot import *
|
||||
from bs4 import BeautifulSoup
|
||||
@ -20,6 +21,40 @@ BASE_PATH = os.path.dirname(__file__)
|
||||
BASE2_PATH = os.path.join(BASE_PATH,'mys')
|
||||
INDEX_PATH = os.path.join(BASE2_PATH,'index')
|
||||
|
||||
async def get_alots(qid):
|
||||
conn = sqlite3.connect('ID_DATA.db')
|
||||
c = conn.cursor()
|
||||
c.execute('''CREATE TABLE IF NOT EXISTS UseridDict
|
||||
(QID INT PRIMARY KEY NOT NULL,
|
||||
lots TEXT,
|
||||
cache TEXT,
|
||||
permission TEXT,
|
||||
Status TEXT,
|
||||
Subscribe TEXT,
|
||||
Extra TEXT);''')
|
||||
cursor = c.execute("SELECT * from UseridDict WHERE QID = ?",(qid,))
|
||||
c_data = cursor.fetchall()
|
||||
with open(os.path.join(INDEX_PATH,'lots.txt'),"r") as f:
|
||||
raw_data = f.read()
|
||||
raw_data = raw_data.replace(' ', "").split('-')
|
||||
|
||||
if len(c_data) == 0:
|
||||
num = random.randint(1,len(raw_data)-1)
|
||||
data = raw_data[num]
|
||||
c.execute("INSERT OR IGNORE INTO UseridDict (QID,lots) \
|
||||
VALUES (?, ?)",(qid,str(num)))
|
||||
else:
|
||||
if c_data[0][1] == None:
|
||||
num = random.randint(0,len(raw_data)-1)
|
||||
data = raw_data[num]
|
||||
c.execute("UPDATE UseridDict SET lots = ? WHERE QID=?",(str(num),qid))
|
||||
else:
|
||||
num = int(c_data[0][1])
|
||||
data = raw_data[num]
|
||||
conn.commit()
|
||||
conn.close()
|
||||
return data
|
||||
|
||||
async def OpenPush(uid,qid,status,mode):
|
||||
conn = sqlite3.connect('ID_DATA.db')
|
||||
c = conn.cursor()
|
||||
@ -158,6 +193,15 @@ def deletecache():
|
||||
conn.close()
|
||||
except:
|
||||
print("\nerror\n")
|
||||
|
||||
try:
|
||||
conn = sqlite3.connect('ID_DATA.db')
|
||||
c = conn.cursor()
|
||||
c.execute("UPDATE UseridDict SET lots=NULL")
|
||||
conn.commit()
|
||||
conn.close()
|
||||
except:
|
||||
print("\nerror\n")
|
||||
|
||||
def errorDB(ck,err):
|
||||
conn = sqlite3.connect('ID_DATA.db')
|
||||
@ -408,7 +452,6 @@ async def GetSignInfo(Uid,ServerID="cn_gf01"):
|
||||
return data
|
||||
except:
|
||||
im = "获取签到信息失败,请重试"
|
||||
print(im)
|
||||
|
||||
async def MysSign(Uid,ServerID="cn_gf01"):
|
||||
if Uid[0] == '5':
|
||||
@ -556,22 +599,64 @@ async def GetWeaponInfo(name):
|
||||
data = json.loads(item)
|
||||
return data
|
||||
|
||||
async def GetCharInfo(name,mode = 0):
|
||||
async def GetCharInfo(name,mode = 0,level = None):
|
||||
str = ""
|
||||
if mode == 1:
|
||||
str = "&talents=1"
|
||||
elif mode == 2:
|
||||
str = "&constellations=1"
|
||||
|
||||
async with AsyncClient() as client:
|
||||
|
||||
req = await client.get(
|
||||
url="https://genshin.minigg.cn/?characters=" + name + str,
|
||||
headers={
|
||||
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36',
|
||||
'Referer': 'https://genshin.minigg.cn/index.html'})
|
||||
|
||||
baseurl = "https://genshin.minigg.cn/?characters="
|
||||
|
||||
detailurl = "https://api.minigg.cn/characters?query="
|
||||
|
||||
if level:
|
||||
async with AsyncClient() as client:
|
||||
req = await client.get(
|
||||
url = detailurl + name + "&stats=" + level,
|
||||
headers={
|
||||
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36',
|
||||
'Referer': 'https://genshin.minigg.cn/index.html'})
|
||||
data = jsonfy(req.text)
|
||||
else:
|
||||
async with AsyncClient() as client:
|
||||
req = await client.get(
|
||||
url = baseurl + name + str,
|
||||
headers={
|
||||
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36',
|
||||
'Referer': 'https://genshin.minigg.cn/index.html'})
|
||||
|
||||
soup = BeautifulSoup(req.text, "lxml")
|
||||
item = soup.select_one("pre").text
|
||||
if item:
|
||||
data = json.loads(item)
|
||||
else:
|
||||
async with AsyncClient() as client:
|
||||
req = await client.get(
|
||||
url = detailurl + name + "&matchCategories=true",
|
||||
headers={
|
||||
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36',
|
||||
'Referer': 'https://genshin.minigg.cn/index.html'})
|
||||
data = req.text
|
||||
|
||||
soup = BeautifulSoup(req.text, "lxml")
|
||||
item = soup.select_one("pre").text
|
||||
data = json.loads(item)
|
||||
return data
|
||||
|
||||
async def GetGenshinEvent(mode = "List"):
|
||||
if mode == "Calendar":
|
||||
now_time = datetime.datetime.now().strftime('%Y-%m-%d')
|
||||
base_url = "https://api-takumi.mihoyo.com/event/bbs_activity_calendar/getActList?time={}&game_biz=ys_cn&page=1&tag_id=0".format(now_time)
|
||||
else:
|
||||
base_url = "https://hk4e-api.mihoyo.com/common/hk4e_cn/announcement/api/getAnn" + mode + "?game=hk4e&game_biz=hk4e_cn&lang=zh-cn&bundle_id=hk4e_cn&platform=pc®ion=cn_gf01&level=55&uid=100000000"
|
||||
|
||||
async with AsyncClient() as client:
|
||||
req = await client.get(
|
||||
url = base_url,
|
||||
headers={
|
||||
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36'})
|
||||
data = json.loads(req.text)
|
||||
return data
|
||||
|
||||
def jsonfy(s:str)->object:
|
||||
#此函数将不带双引号的json的key标准化
|
||||
obj = eval(s, type('js', (dict,), dict(__getitem__=lambda s, n: n))())
|
||||
return obj
|
||||
|
482
getImg.py
@ -5,12 +5,14 @@ from io import BytesIO
|
||||
import urllib
|
||||
import math
|
||||
import threading
|
||||
import requests
|
||||
from bs4 import BeautifulSoup
|
||||
from wordcloud import WordCloud
|
||||
import numpy as np
|
||||
|
||||
from PIL import Image, ImageDraw, ImageFont, ImageFilter
|
||||
|
||||
from .getDB import GetInfo,GetCharacter,GetSpiralAbyssInfo,GetMysInfo,errorDB,cacheDB,OwnerCookies
|
||||
from .getDB import GetInfo,GetCharacter,GetSpiralAbyssInfo,GetMysInfo,errorDB,cacheDB,OwnerCookies,GetGenshinEvent
|
||||
|
||||
import os
|
||||
import json
|
||||
@ -60,6 +62,12 @@ def get_chardone_pic(id,url,star):
|
||||
def get_weapon_pic(url):
|
||||
urllib.request.urlretrieve(url, os.path.join(WEAPON_PATH, url.split('/')[-1]))
|
||||
|
||||
def get_charimg_pic(url):
|
||||
urllib.request.urlretrieve(url, os.path.join(CHAR_IMG_PATH, url.split('/')[-1]))
|
||||
|
||||
def get_rel_pic(url):
|
||||
urllib.request.urlretrieve(url, os.path.join(REL_PATH, url.split('/')[-1]))
|
||||
|
||||
async def draw_wordcloud(uid,image = None,mode = 2):
|
||||
while 1:
|
||||
use_cookies = cacheDB(uid,mode-1)
|
||||
@ -233,7 +241,6 @@ async def draw_wordcloud(uid,image = None,mode = 2):
|
||||
word_str["初心者"] = l2_size
|
||||
elif raw_data['stats']['active_day_number'] <= 300:
|
||||
word_str["老玩家"] = l2_size
|
||||
|
||||
if raw_data['stats']['active_day_number'] >=365 and raw_data['stats']['magic_chest_number'] + raw_data['stats']['common_chest_number']+raw_data['stats']['exquisite_chest_number']+raw_data['stats']['precious_chest_number']+raw_data['stats']['luxurious_chest_number'] <=2500:
|
||||
word_str["老咸鱼"] = l3_size
|
||||
if raw_data['stats']['magic_chest_number'] >= 46:
|
||||
@ -824,6 +831,7 @@ async def draw_abyss_pic(uid,nickname,floor_num,image = None,mode = 2,date = "1"
|
||||
return resultmes
|
||||
|
||||
async def draw_pic(uid,nickname,image = None,mode = 2,role_level = None):
|
||||
#获取Cookies,如果没有能使用的则return
|
||||
while 1:
|
||||
use_cookies = cacheDB(uid,mode-1)
|
||||
if use_cookies == '':
|
||||
@ -843,96 +851,84 @@ async def draw_pic(uid,nickname,image = None,mode = 2,role_level = None):
|
||||
|
||||
raw_data = await GetInfo(uid,use_cookies)
|
||||
|
||||
if (raw_data["retcode"] != 0):
|
||||
if (raw_data["retcode"] == 10001):
|
||||
if raw_data["retcode"] != 0:
|
||||
if raw_data["retcode"] == 10001:
|
||||
#return ("Cookie错误/过期,请重置Cookie")
|
||||
errorDB(use_cookies,"error")
|
||||
elif (raw_data["retcode"] == 10101):
|
||||
elif raw_data["retcode"] == 10101:
|
||||
#return ("当前cookies已达到30人上限!")
|
||||
errorDB(use_cookies,"limit30")
|
||||
elif (raw_data["retcode"] == 10102):
|
||||
elif raw_data["retcode"] == 10102:
|
||||
return ("当前查询id已经设置了隐私,无法查询!")
|
||||
return (
|
||||
"Api报错,返回内容为:\r\n"
|
||||
+ str(raw_data) + "\r\n出现这种情况可能的UID输入错误 or 不存在"
|
||||
)
|
||||
else:
|
||||
return (
|
||||
"Api报错,返回内容为:\r\n"
|
||||
+ str(raw_data) + "\r\n出现这种情况可能的UID输入错误 or 不存在"
|
||||
)
|
||||
else:
|
||||
break
|
||||
|
||||
bg_list = random.choice([x for x in os.listdir(BG_PATH)
|
||||
if os.path.isfile(os.path.join(BG_PATH, x))])
|
||||
|
||||
bg2_path = os.path.join(BG_PATH,bg_list)
|
||||
|
||||
if role_level:
|
||||
panle1_path = os.path.join(TEXT_PATH,"mys_1.png")
|
||||
else:
|
||||
panle1_path = os.path.join(TEXT_PATH,"panle_1.png")
|
||||
panle2_path = os.path.join(TEXT_PATH,"panle_2.png")
|
||||
panle3_path = os.path.join(TEXT_PATH,"panle_3.png")
|
||||
|
||||
#获取背景图片
|
||||
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(requests.get(image_data).content))
|
||||
else:
|
||||
edit_bg = Image.open(bg2_path)
|
||||
|
||||
#获取背景主色
|
||||
q = edit_bg.quantize(colors=3,method=2)
|
||||
bg_num_temp = 0
|
||||
for i in range(0,3):
|
||||
bg = tuple(q.getpalette()[i*3:(i*3)+3])
|
||||
bg_num = bg[0] + bg[1] + bg[2]
|
||||
if bg_num >= bg_num_temp:
|
||||
bg_num_temp = bg_num
|
||||
bg_color = (bg[0],bg[1],bg[2])
|
||||
|
||||
#通过背景主色(bg_color)确定文字主色
|
||||
r = 140
|
||||
if max(*bg_color) > 255 - r:
|
||||
r *= -1
|
||||
new_color = (math.floor(bg_color[0] + r if bg_color[0] + r <= 255 else 255),
|
||||
math.floor(bg_color[1] + r if bg_color[1] + r <= 255 else 255),
|
||||
math.floor(bg_color[2] + r if bg_color[2] + r <= 255 else 255))
|
||||
|
||||
#确定texture2D路径
|
||||
panle1_path = os.path.join(TEXT_PATH,"panle_1.png")
|
||||
panle3_path = os.path.join(TEXT_PATH,"panle_3.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")
|
||||
|
||||
#记录数据
|
||||
raw_data = raw_data['data']
|
||||
char_data = raw_data["avatars"]
|
||||
#char_num = len(raw_data["avatars"])
|
||||
|
||||
char_datas = []
|
||||
char_ids = []
|
||||
char_rawdata = []
|
||||
|
||||
is_owner = await OwnerCookies(uid)
|
||||
if is_owner == None:
|
||||
def get_charid(start,end):
|
||||
for i in range(start,end):
|
||||
char_rawdata = GetCharacter(uid,[i],use_cookies)
|
||||
|
||||
if char_rawdata["retcode"] == -1:
|
||||
pass
|
||||
else:
|
||||
char_datas.append(char_rawdata["data"]['avatars'][0])
|
||||
for i in char_data:
|
||||
char_ids.append(i["id"])
|
||||
|
||||
thread_list = []
|
||||
st = 8
|
||||
for i in range(0,8):
|
||||
thread = threading.Thread(target = get_charid,args = (10000002+i*st,10000002+(i+1)*st))
|
||||
thread_list.append(thread)
|
||||
|
||||
for t in thread_list:
|
||||
t.setDaemon(True)
|
||||
t.start()
|
||||
|
||||
for t in thread_list:
|
||||
t.join()
|
||||
|
||||
else:
|
||||
char_ids = []
|
||||
char_rawdata = []
|
||||
|
||||
for i in char_data:
|
||||
char_ids.append(i["id"])
|
||||
|
||||
char_rawdata = GetCharacter(uid,char_ids,use_cookies)
|
||||
char_datas = char_rawdata["data"]["avatars"]
|
||||
char_rawdata = GetCharacter(uid,char_ids,use_cookies)
|
||||
char_datas = char_rawdata["data"]["avatars"]
|
||||
|
||||
#确定角色占用行数
|
||||
char_num = len(char_datas)
|
||||
|
||||
char_hang = 1 + (char_num-1)//6
|
||||
char_lie = char_num%6
|
||||
char_hang = 1 + (char_num-1)//6 if char_num > 8 else char_num
|
||||
|
||||
#确定整体图片的长宽
|
||||
based_w = 900
|
||||
based_h = 890+char_hang*130
|
||||
based_h = 890+char_hang*130 if char_num > 8 else 890+char_hang*110
|
||||
based_scale = '%.3f' % (based_w/based_h)
|
||||
|
||||
is_edit = False
|
||||
if image:
|
||||
image_file= image.group(1)
|
||||
image_data = image.group(2)
|
||||
urllib.request.urlretrieve(f'{image_data}', os.path.join(TEXT_PATH,nickname + '.png'))
|
||||
is_edit = True
|
||||
|
||||
if is_edit == True:
|
||||
bg_path_edit = os.path.join(TEXT_PATH,f"{nickname}.png")
|
||||
else:
|
||||
bg_path_edit = bg2_path
|
||||
|
||||
edit_bg = Image.open(bg_path_edit)
|
||||
#通过确定的长宽比,缩放背景图片
|
||||
w, h = edit_bg.size
|
||||
scale_f = '%.3f' % (w / h)
|
||||
new_w = math.ceil(based_h*float(scale_f))
|
||||
@ -941,131 +937,124 @@ async def draw_pic(uid,nickname,image = None,mode = 2,role_level = None):
|
||||
bg_img2 = edit_bg.resize((new_w, based_h),Image.ANTIALIAS)
|
||||
else:
|
||||
bg_img2 = edit_bg.resize((based_w, new_h),Image.ANTIALIAS)
|
||||
|
||||
bg_img = bg_img2.crop((0, 0, 900, based_h))
|
||||
|
||||
x, y = 45, 268
|
||||
radius = 50
|
||||
cropped_img = bg_img.crop((x, y, 856, based_h-45))
|
||||
blurred_img = cropped_img.filter(ImageFilter.GaussianBlur(5),).convert("RGBA")
|
||||
bg_img.paste(blurred_img, (x, y), create_rounded_rectangle_mask(cropped_img,radius))
|
||||
#转换遮罩的颜色、大小匹配,并paste上去
|
||||
all_mask = Image.open(all_mask_path).resize(bg_img.size,Image.ANTIALIAS)
|
||||
all_mask_img = Image.new("RGBA",(based_w,based_h),bg_color)
|
||||
bg_img.paste(all_mask_img,(0,0),all_mask)
|
||||
|
||||
#操作图片
|
||||
panle1 = Image.open(panle1_path)
|
||||
panle2 = Image.open(panle2_path)
|
||||
panle3 = Image.open(panle3_path)
|
||||
avatar_bg = Image.open(avatar_bg_path)
|
||||
avatar_fg = Image.open(avatar_fg_path)
|
||||
|
||||
bg_img.paste(panle1,(0,0),panle1)
|
||||
for i in range(0,char_hang):
|
||||
bg_img.paste(panle2,(0,800+i*130),panle2)
|
||||
bg_img.paste(panle3,(0,char_hang*130+800),panle3)
|
||||
#确定主体框架
|
||||
avatar_bg_color = Image.new("RGBA",(316,100),bg_color)
|
||||
panle1_color = Image.new("RGBA",(900,800),new_color)
|
||||
bg_img.paste(panle1_color,(0,0),panle1)
|
||||
bg_img.paste(panle3,(0,char_hang*130+800) if char_num > 8 else (0,char_hang*110+800),panle3)
|
||||
bg_img.paste(avatar_bg_color,(113,98),avatar_bg)
|
||||
bg_img.paste(avatar_fg,(114,95),avatar_fg)
|
||||
|
||||
#绘制基础信息文字
|
||||
text_draw = ImageDraw.Draw(bg_img)
|
||||
|
||||
if role_level:
|
||||
text_draw.text((310,193), f"{role_level}", (29,30,63), ys_font(20))
|
||||
text_draw.text((140,200), "冒险等级:" + f"{role_level}", new_color, ys_font(20))
|
||||
|
||||
text_draw.text((242.6,128.3), f"{nickname}", (217,217,217), ys_font(32))
|
||||
text_draw.text((260.6, 165.3), 'UID ' + f"{uid}", (217,217,217), ys_font(14))
|
||||
text_draw.text((220,123), f"{nickname}", new_color, ys_font(32))
|
||||
text_draw.text((235, 163), 'UID ' + f"{uid}", new_color, ys_font(14))
|
||||
|
||||
text_draw.text((640, 94.8),str(raw_data['stats']['active_day_number']), (65, 65, 65), ys_font(26))
|
||||
text_draw.text((640, 139.3),str(raw_data['stats']['achievement_number']), (65, 65, 65), ys_font(26))
|
||||
text_draw.text((640, 183.9),raw_data['stats']['spiral_abyss'], (65, 65, 65), ys_font(26))
|
||||
#活跃天数/成就数量/深渊信息
|
||||
text_draw.text((640, 94.8),str(raw_data['stats']['active_day_number']), new_color, ys_font(26))
|
||||
text_draw.text((640, 139.3),str(raw_data['stats']['achievement_number']), new_color, ys_font(26))
|
||||
text_draw.text((640, 183.9),raw_data['stats']['spiral_abyss'], new_color, ys_font(26))
|
||||
|
||||
text_draw.text((258, 382.4),str(raw_data['stats']['magic_chest_number']), (65, 65, 65), ys_font(24))
|
||||
text_draw.text((258, 442),str(raw_data['stats']['common_chest_number']),(65, 65, 65), ys_font(24))
|
||||
text_draw.text((258, 501.6),str(raw_data['stats']['exquisite_chest_number']),(65, 65, 65), ys_font(24))
|
||||
text_draw.text((258, 561.2),str(raw_data['stats']['precious_chest_number']), (65, 65, 65), ys_font(24))
|
||||
text_draw.text((258, 620.8),str(raw_data['stats']['luxurious_chest_number']), (65, 65, 65), ys_font(24))
|
||||
#宝箱
|
||||
text_draw.text((258, 382.4),str(raw_data['stats']['magic_chest_number']), new_color, ys_font(24))
|
||||
text_draw.text((258, 442),str(raw_data['stats']['common_chest_number']),new_color, ys_font(24))
|
||||
text_draw.text((258, 501.6),str(raw_data['stats']['exquisite_chest_number']),new_color, ys_font(24))
|
||||
text_draw.text((258, 561.2),str(raw_data['stats']['precious_chest_number']), new_color, ys_font(24))
|
||||
text_draw.text((258, 620.8),str(raw_data['stats']['luxurious_chest_number']), new_color, ys_font(24))
|
||||
|
||||
text_draw.text((258, 680.4),str(raw_data['stats']['avatar_number']),(65, 65, 65), ys_font(24))
|
||||
#已获角色
|
||||
text_draw.text((258, 680.4),str(raw_data['stats']['avatar_number']),new_color, ys_font(24))
|
||||
|
||||
text_draw.text((745, 474.5),str(raw_data['stats']['way_point_number']),(65, 65, 65), ys_font(24))
|
||||
text_draw.text((745, 514),str(raw_data['stats']['domain_number']),(65, 65, 65), ys_font(24))
|
||||
#开启锚点和秘境数量
|
||||
text_draw.text((745, 474.5),str(raw_data['stats']['way_point_number']),new_color, ys_font(24))
|
||||
text_draw.text((745, 514),str(raw_data['stats']['domain_number']),new_color, ys_font(24))
|
||||
|
||||
#蒙德
|
||||
text_draw.text((490, 370),str(raw_data['world_explorations'][3]['exploration_percentage']/10) + '%',(65, 65, 65), ys_font(22))
|
||||
text_draw.text((490, 400),'lv.' + str(raw_data['world_explorations'][3]['level']),(65, 65, 65), ys_font(22))
|
||||
text_draw.text((513, 430), str(raw_data['stats']['anemoculus_number']), (65, 65, 65), ys_font(22))
|
||||
text_draw.text((490, 370),str(raw_data['world_explorations'][3]['exploration_percentage']/10) + '%',new_color, ys_font(22))
|
||||
text_draw.text((490, 400),'lv.' + str(raw_data['world_explorations'][3]['level']),new_color, ys_font(22))
|
||||
text_draw.text((513, 430), str(raw_data['stats']['anemoculus_number']), new_color, ys_font(22))
|
||||
|
||||
#璃月
|
||||
text_draw.text((490, 490),str(raw_data['world_explorations'][2]['exploration_percentage']/10) + '%',(65, 65, 65), ys_font(22))
|
||||
text_draw.text((490, 520),'lv.' + str(raw_data['world_explorations'][2]['level']),(65, 65, 65), ys_font(22))
|
||||
text_draw.text((513, 550), str(raw_data['stats']['geoculus_number']), (65, 65, 65), ys_font(22))
|
||||
text_draw.text((490, 490),str(raw_data['world_explorations'][2]['exploration_percentage']/10) + '%',new_color, ys_font(22))
|
||||
text_draw.text((490, 520),'lv.' + str(raw_data['world_explorations'][2]['level']),new_color, ys_font(22))
|
||||
text_draw.text((513, 550), str(raw_data['stats']['geoculus_number']), new_color, ys_font(22))
|
||||
|
||||
#雪山
|
||||
text_draw.text((745, 379.5),str(raw_data['world_explorations'][1]['exploration_percentage']/10) + '%',(65, 65, 65), ys_font(22))
|
||||
text_draw.text((745, 413.1),'lv.' + str(raw_data['world_explorations'][1]['level']),(65, 65, 65), ys_font(22))
|
||||
text_draw.text((745, 379.5),str(raw_data['world_explorations'][1]['exploration_percentage']/10) + '%',new_color, ys_font(22))
|
||||
text_draw.text((745, 413.1),'lv.' + str(raw_data['world_explorations'][1]['level']),new_color, ys_font(22))
|
||||
|
||||
#稻妻
|
||||
text_draw.text((490, 608),str(raw_data['world_explorations'][0]['exploration_percentage']/10) + '%',(65, 65, 65), ys_font(22))
|
||||
text_draw.text((490, 635),'lv.' + str(raw_data['world_explorations'][0]['level']),(65, 65, 65), ys_font(22))
|
||||
text_draw.text((490, 662),'lv.' + str(raw_data['world_explorations'][0]['offerings'][0]['level']),(65, 65, 65), ys_font(22))
|
||||
text_draw.text((513, 689), str(raw_data['stats']['electroculus_number']), (65, 65, 65), ys_font(22))
|
||||
text_draw.text((490, 608),str(raw_data['world_explorations'][0]['exploration_percentage']/10) + '%',new_color, ys_font(22))
|
||||
text_draw.text((490, 635),'lv.' + str(raw_data['world_explorations'][0]['level']),new_color, ys_font(22))
|
||||
text_draw.text((490, 662),'lv.' + str(raw_data['world_explorations'][0]['offerings'][0]['level']),new_color, ys_font(22))
|
||||
text_draw.text((513, 689), str(raw_data['stats']['electroculus_number']), new_color, ys_font(22))
|
||||
|
||||
#家园
|
||||
if len(raw_data['homes']):
|
||||
text_draw.text((693, 572.4),'lv.' + str(raw_data['homes'][0]['level']),(65, 65, 65), ys_font(22))
|
||||
text_draw.text((693, 610.4),str(raw_data['homes'][0]['visit_num']),(65, 65, 65), ys_font(22))
|
||||
text_draw.text((693, 648.4),str(raw_data['homes'][0]['item_num']),(65, 65, 65), ys_font(22))
|
||||
text_draw.text((693, 686.4),str(raw_data['homes'][0]['comfort_num']),(65, 65, 65), ys_font(22))
|
||||
text_draw.text((693, 572.4),'lv.' + str(raw_data['homes'][0]['level']),new_color, ys_font(22))
|
||||
text_draw.text((693, 610.4),str(raw_data['homes'][0]['visit_num']),new_color, ys_font(22))
|
||||
text_draw.text((693, 648.4),str(raw_data['homes'][0]['item_num']),new_color, ys_font(22))
|
||||
text_draw.text((693, 686.4),str(raw_data['homes'][0]['comfort_num']),new_color, ys_font(22))
|
||||
else:
|
||||
text_draw.text((693, 572.4),"未开",(65, 65, 65), ys_font(22))
|
||||
text_draw.text((693, 610.4),"未开",(65, 65, 65), ys_font(22))
|
||||
text_draw.text((693, 648.4),"未开",(65, 65, 65), ys_font(22))
|
||||
text_draw.text((693, 686.4),"未开",(65, 65, 65), ys_font(22))
|
||||
text_draw.text((693, 572.4),"未开",new_color, ys_font(22))
|
||||
text_draw.text((693, 610.4),"未开",new_color, ys_font(22))
|
||||
text_draw.text((693, 648.4),"未开",new_color, ys_font(22))
|
||||
text_draw.text((693, 686.4),"未开",new_color, ys_font(22))
|
||||
|
||||
if mode == 1:
|
||||
char_data.sort(key=lambda x: (-x['rarity'],-x['level'],-x['fetter']))
|
||||
num = 0
|
||||
for i in raw_data['avatars']:
|
||||
if not os.path.exists(os.path.join(CHAR_DONE_PATH,str(char_data[num]['id']) + ".png")):
|
||||
get_char_pic(char_data[num]['id'],char_data[num]['image'],char_data[num]['rarity'])
|
||||
char = os.path.join(CHAR_DONE_PATH,str(char_data[num]['id']) + ".png")
|
||||
char_img = Image.open(char)
|
||||
char_draw = ImageDraw.Draw(char_img)
|
||||
char_draw.text((40,108),f'Lv.{str(char_data[num]["level"])}',(21,21,21),ys_font(18))
|
||||
char_draw.text((95.3,19),f'{str(char_data[num]["actived_constellation_num"])}','white',ys_font(18))
|
||||
if str(char_data[num]["fetter"]) == "10" or str(char_data[num]["name"]) == "旅行者":
|
||||
char_draw.text((93,41.5),"♥",(21,21,21),ys_font(15))
|
||||
else:
|
||||
char_draw.text((95.3,40.5),f'{str(char_data[num]["fetter"])}',(21,21,21),ys_font(18))
|
||||
|
||||
char_crop = (68+129*(num%6),800+130*(num//6))
|
||||
bg_img.paste(char_img,char_crop,char_img)
|
||||
num = num+1
|
||||
else:
|
||||
charpic_mask_path = os.path.join(TEXT_PATH,"charpic_mask.png")
|
||||
weaponpic_mask_path = os.path.join(TEXT_PATH,"weaponpic_mask.png")
|
||||
s5s1_path = os.path.join(TEXT_PATH,"5s_1.png")
|
||||
s5s2_path = os.path.join(TEXT_PATH,"5s_2.png")
|
||||
s5s3_path = os.path.join(TEXT_PATH,"5s_3.png")
|
||||
s5s4_path = os.path.join(TEXT_PATH,"5s_4.png")
|
||||
s4s1_path = os.path.join(TEXT_PATH,"4s_1.png")
|
||||
s4s2_path = os.path.join(TEXT_PATH,"4s_2.png")
|
||||
s4s3_path = os.path.join(TEXT_PATH,"4s_3.png")
|
||||
s4s4_path = os.path.join(TEXT_PATH,"4s_4.png")
|
||||
#确定texture2D路径
|
||||
charpic_mask_path = os.path.join(TEXT_PATH,"charpic_mask.png")
|
||||
weaponpic_mask_path = os.path.join(TEXT_PATH,"weaponpic_mask.png")
|
||||
|
||||
s3s3_path = os.path.join(TEXT_PATH,"3s_3.png")
|
||||
s2s3_path = os.path.join(TEXT_PATH,"2s_3.png")
|
||||
s1s3_path = os.path.join(TEXT_PATH,"1s_3.png")
|
||||
def getText(star,step):
|
||||
return os.path.join(TEXT_PATH,"{}s_{}.png".format(str(star),str(step)))
|
||||
|
||||
charpic_mask = Image.open(charpic_mask_path)
|
||||
weaponpic_mask = Image.open(weaponpic_mask_path)
|
||||
s5s1=Image.open(s5s1_path)
|
||||
s5s2=Image.open(s5s2_path)
|
||||
s5s3=Image.open(s5s3_path)
|
||||
s5s4=Image.open(s5s4_path)
|
||||
s4s1=Image.open(s4s1_path)
|
||||
s4s2=Image.open(s4s2_path)
|
||||
s4s3=Image.open(s4s3_path)
|
||||
s4s4=Image.open(s4s4_path)
|
||||
charpic_mask = Image.open(charpic_mask_path)
|
||||
weaponpic_mask = Image.open(weaponpic_mask_path)
|
||||
s5s1=Image.open(getText(5,1))
|
||||
s5s2=Image.open(getText(5,2))
|
||||
s5s3=Image.open(getText(5,3))
|
||||
s5s4=Image.open(getText(5,4))
|
||||
s4s1=Image.open(getText(4,1))
|
||||
s4s2=Image.open(getText(4,2))
|
||||
s4s3=Image.open(getText(4,3))
|
||||
s4s4=Image.open(getText(4,4))
|
||||
s3s3=Image.open(getText(3,3))
|
||||
s2s3=Image.open(getText(2,3))
|
||||
s1s3=Image.open(getText(1,3))
|
||||
|
||||
s3s3=Image.open(s3s3_path)
|
||||
s2s3=Image.open(s2s3_path)
|
||||
s1s3=Image.open(s1s3_path)
|
||||
char_bg_path = os.path.join(TEXT_PATH, "char_bg.png")
|
||||
char_fg_path = os.path.join(TEXT_PATH, "char_fg.png")
|
||||
|
||||
num = 0
|
||||
char_datas.sort(key=lambda x: (-x['rarity'],-x['level'],-x['fetter']))
|
||||
char_bg = Image.open(char_bg_path)
|
||||
char_fg = Image.open(char_fg_path)
|
||||
|
||||
char_color = (math.floor(bg_color[0] + 10 if bg_color[0] + r <= 255 else 255),
|
||||
math.floor(bg_color[1] + 10 if bg_color[1] + r <= 255 else 255),
|
||||
math.floor(bg_color[2] + 10 if bg_color[2] + r <= 255 else 255))
|
||||
|
||||
charset_mask = Image.new("RGBA",(900,130),char_color)
|
||||
|
||||
num = 0
|
||||
char_datas.sort(key=lambda x: (-x['rarity'],-x['level'],-x['fetter']))
|
||||
|
||||
if char_num > 8 :
|
||||
for i in char_datas:
|
||||
char_mingzuo = 0
|
||||
for k in i['constellations']:
|
||||
@ -1078,10 +1067,7 @@ async def draw_pic(uid,nickname,image = None,mode = 2,role_level = None):
|
||||
char_fetter = i['fetter']
|
||||
char_rarity = i['rarity']
|
||||
|
||||
char_weapon = i['weapon']
|
||||
char_weapon_star = i['weapon']['rarity']
|
||||
char_weapon_name = i['weapon']['name']
|
||||
char_weapon_level = i['weapon']['level']
|
||||
char_weapon_jinglian = i['weapon']['affix_level']
|
||||
char_weapon_icon = i['weapon']['icon']
|
||||
|
||||
@ -1154,7 +1140,94 @@ async def draw_pic(uid,nickname,image = None,mode = 2,role_level = None):
|
||||
char_crop = (68+129*(num%6),800+130*(num//6))
|
||||
bg_img.paste(charpic,char_crop,charpic)
|
||||
num = num+1
|
||||
else:
|
||||
for i in char_datas:
|
||||
char_mingzuo = 0
|
||||
for k in i['constellations']:
|
||||
if k['is_actived'] == True:
|
||||
char_mingzuo += 1
|
||||
|
||||
char_name = i["name"]
|
||||
char_id = i["id"]
|
||||
char_level = i["level"]
|
||||
char_fetter = i['fetter']
|
||||
char_rarity = i['rarity']
|
||||
char_img_icon = i["image"]
|
||||
|
||||
char_weapon_star = i['weapon']['rarity']
|
||||
char_weapon_jinglian = i['weapon']['affix_level']
|
||||
char_weapon_icon = i['weapon']['icon']
|
||||
|
||||
if not os.path.exists(os.path.join(WEAPON_PATH, str(char_weapon_icon.split('/')[-1]))):
|
||||
get_weapon_pic(char_weapon_icon)
|
||||
if not os.path.exists(os.path.join(CHAR_IMG_PATH, str(char_img_icon.split('/')[-1]))):
|
||||
get_charimg_pic(char_img_icon)
|
||||
if not os.path.exists(os.path.join(CHAR_PATH,str(i['id']) + ".png")):
|
||||
get_char_pic(i['id'],i['icon'])
|
||||
|
||||
char = os.path.join(CHAR_PATH,str(char_id) + ".png")
|
||||
weapon = os.path.join(WEAPON_PATH, str(char_weapon_icon.split('/')[-1]))
|
||||
char_stand_img = os.path.join(CHAR_IMG_PATH,str(char_img_icon.split('/')[-1]))
|
||||
char_stand_mask = Image.open(os.path.join(TEXT_PATH,"stand_mask.png"))
|
||||
|
||||
char_stand = Image.open(char_stand_img)
|
||||
char_img = Image.open(char)
|
||||
char_img = char_img.resize((100,100),Image.ANTIALIAS)
|
||||
weapon_img = Image.open(weapon)
|
||||
weapon_img = weapon_img.resize((47,47),Image.ANTIALIAS)
|
||||
|
||||
charpic = Image.new("RGBA", (900, 130))
|
||||
charpic_temp = Image.new("RGBA", (900, 130))
|
||||
|
||||
charpic.paste(charset_mask,(0,0),char_bg)
|
||||
|
||||
weapon_bg = Image.open(getText(char_weapon_star,3))
|
||||
charpic.paste(weapon_bg,(72,10),weapon_bg)
|
||||
charpic_temp.paste(char_img,(81,13),charpic_mask)
|
||||
charpic_temp.paste(char_stand,(335,-99),char_stand_mask)
|
||||
charpic_temp.paste(char_fg,(0,0),char_fg)
|
||||
charpic_temp.paste(weapon_img,(141,72),weaponpic_mask)
|
||||
#temp = Image.composite(weapon_img, basedb, weaponpic_mask)
|
||||
charpic.paste(charpic_temp,(0,0),charpic_temp)
|
||||
|
||||
|
||||
for _,k in enumerate(i["reliquaries"]):
|
||||
if not os.path.exists(os.path.join(REL_PATH, str(k["icon"].split('/')[-1]))):
|
||||
get_rel_pic(k["icon"])
|
||||
rel = os.path.join(REL_PATH,str(k["icon"].split('/')[-1]))
|
||||
rel_img = Image.open(rel).resize((43,43),Image.ANTIALIAS)
|
||||
rel_bg = Image.open(getText(k["rarity"],3))
|
||||
|
||||
if k["pos_name"] == "生之花":
|
||||
charpic.paste(rel_bg,(287 + 55 * 0,-14),rel_bg)
|
||||
charpic.paste(rel_img,(360 + 55 * 0,49),rel_img)
|
||||
elif k["pos_name"] == "死之羽":
|
||||
charpic.paste(rel_bg,(287 + 55 * 1,-14),rel_bg)
|
||||
charpic.paste(rel_img,(360 + 55 * 1,49),rel_img)
|
||||
elif k["pos_name"] == "时之沙":
|
||||
charpic.paste(rel_bg,(287 + 55 * 2,-14),rel_bg)
|
||||
charpic.paste(rel_img,(360 + 55 * 2,49),rel_img)
|
||||
elif k["pos_name"] == "空之杯":
|
||||
charpic.paste(rel_bg,(287 + 55 * 3,-14),rel_bg)
|
||||
charpic.paste(rel_img,(360 + 55 * 3,49),rel_img)
|
||||
elif k["pos_name"] == "理之冠":
|
||||
charpic.paste(rel_bg,(287 + 55 * 4,-14),rel_bg)
|
||||
charpic.paste(rel_img,(360 + 55 * 4,49),rel_img)
|
||||
|
||||
char_draw = ImageDraw.Draw(charpic)
|
||||
|
||||
char_draw.text((182,39),i["name"],new_color,ys_font(22))
|
||||
char_draw.text((272,45),f'Lv.{str(char_level)}',new_color,ys_font(18))
|
||||
|
||||
#char_draw.text((104.5,91.5),f'{str(char_weapon_jinglian)}',new_color,ys_font(10))
|
||||
char_draw.text((267,77),f'{str(char_mingzuo)}',new_color,ys_font(18))
|
||||
|
||||
char_draw.text((209,77),f'{str(i["fetter"])}' if str(char_name) != "旅行者" else "10",new_color,ys_font(18))
|
||||
char_crop = (0,800+110*num)
|
||||
num += 1
|
||||
bg_img.paste(charpic,char_crop,charpic)
|
||||
|
||||
#转换之后发送
|
||||
bg_img = bg_img.convert('RGB')
|
||||
result_buffer = BytesIO()
|
||||
bg_img.save(result_buffer, format='JPEG', subsampling=0, quality=90)
|
||||
@ -1181,4 +1254,75 @@ def create_rounded_rectangle_mask(rectangle, radius):
|
||||
draw.rectangle( [(radius,0),(mx-radius,my)],fill=solid_fill)
|
||||
draw.rectangle( [(0,radius),(mx,my-radius)],fill=solid_fill)
|
||||
|
||||
return i
|
||||
return i
|
||||
|
||||
async def draw_event_pic():
|
||||
raw_data = await GetGenshinEvent("List")
|
||||
raw_time_data = await GetGenshinEvent("Calendar")
|
||||
|
||||
data = raw_data["data"]["list"][1]["list"]
|
||||
|
||||
event_data = {"gacha_event":[],"normal_event":[],"other_event":[]}
|
||||
for k in data:
|
||||
for i in raw_time_data["data"]["act_list"]:
|
||||
if i["name"] == k["title"]:
|
||||
k["act_begin_time"] = i["act_begin_time"]
|
||||
k["act_end_time"] = i["act_end_time"]
|
||||
elif "神铸赋形" in k["title"] and "神铸赋形" in i["name"]:
|
||||
k["act_begin_time"] = i["act_begin_time"]
|
||||
k["act_end_time"] = i["act_end_time"]
|
||||
elif "传说任务" in k["title"]:
|
||||
k["act_begin_time"] = k["start_time"]
|
||||
k["act_end_time"] = "永久开放"
|
||||
elif k["subtitle"] in i["name"]:
|
||||
k["act_begin_time"] = i["act_begin_time"]
|
||||
k["act_end_time"] = i["act_end_time"]
|
||||
|
||||
if "冒险助力礼包" in k["title"] or "纪行" in k["title"]:
|
||||
continue
|
||||
#if "角色试用" in k["title"] or "传说任务" in k["title"]:
|
||||
# event_data['other_event'].append(k)
|
||||
elif k["tag_label"] == "扭蛋":
|
||||
event_data['gacha_event'].append(k)
|
||||
elif k["tag_label"] == "活动":
|
||||
event_data['normal_event'].append(k)
|
||||
|
||||
#base_h = 900 + ((1 + (len(event_data['normal_event'])+len(event_data['other_event'])))//2)*390 + ((1 + len(event_data['gacha_event']))//2)*533
|
||||
base_h = 600 + len(event_data['normal_event'])*(390+90) + len(event_data['gacha_event'])*(533+90)
|
||||
base_img = Image.new(mode="RGB",size=(1080,base_h),color=(237,217,195))
|
||||
|
||||
event1_path = os.path.join(TEXT_PATH,"event_1.png")
|
||||
event2_path = os.path.join(TEXT_PATH,"event_2.png")
|
||||
#event3_path = os.path.join(TEXT_PATH,"event_3.png")
|
||||
event1 = Image.open(event1_path)
|
||||
event2 = Image.open(event2_path)
|
||||
#event3 = Image.open(event3_path)
|
||||
|
||||
base_img.paste(event1,(0,0),event1)
|
||||
#base_img.paste(event2,(0,300+((1+len(event_data['normal_event']))//2)*390),event2)
|
||||
base_img.paste(event2,(0,len(event_data['normal_event'])*(390+90) + 300),event2)
|
||||
#base_img.paste(event3,(0,600+((1+len(event_data['normal_event']))//2)*390 + ((1 + len(event_data['gacha_event']))//2)*533),event3)
|
||||
|
||||
time_img1 = Image.new(mode="RGB",size=(1080,len(event_data['normal_event'])*(390+90)),color=(237,130,116))
|
||||
time_img2 = Image.new(mode="RGB",size=(1080,len(event_data['gacha_event'])*(533+90)),color=(237,130,116))
|
||||
base_img.paste(time_img1,(0,300))
|
||||
base_img.paste(time_img2,(0,600+len(event_data['normal_event'])*(390+90)))
|
||||
base_draw = ImageDraw.Draw(base_img)
|
||||
for index,value in enumerate(event_data['normal_event']):
|
||||
img = Image.open(BytesIO(requests.get(value["banner"]).content))
|
||||
base_draw.text((540, 300 + 45 + 390 + (390+90)*index+1), value["act_begin_time"] + " —— " + value["act_end_time"], (255,255,255), ys_font(42), anchor="mm")
|
||||
#base_img.paste(img,((index%2)*1080,300 + 390*(index//2)))
|
||||
base_img.paste(img,(0,300 + (390+90)*index))
|
||||
|
||||
for index,value in enumerate(event_data['gacha_event']):
|
||||
img = Image.open(BytesIO(requests.get(value["banner"]).content))
|
||||
base_draw.text((540,600 + 45 + (390+90)*len(event_data['normal_event']) + 533 + index * (533 + 90)), value["act_begin_time"] + " —— " + value["act_end_time"], (255,255,255), ys_font(42), anchor="mm")
|
||||
#base_img.paste(img,((index%2)*1080,600 + ((1 + len(event_data['normal_event']))//2)*390 + 533*(index//2)))
|
||||
base_img.paste(img,(0,600 + (390+90) * len(event_data['normal_event']) + index * (533 + 90)))
|
||||
#for index,value in enumerate(event_data['other_event']):
|
||||
# img = Image.open(BytesIO(requests.get(value["banner"]).content))
|
||||
# base_img.paste(img,((index%2)*1080,900 + ((1 + len(event_data['normal_event']))//2)*390 + ((1 + len(event_data['gacha_event']))//2)*533 + 390*(index//2)))
|
||||
|
||||
base_img = base_img.convert('RGB')
|
||||
base_img.save(os.path.join(FILE2_PATH,'event.jpg'), format='JPEG', subsampling=0, quality=90)
|
||||
return
|
BIN
mys/bg/2.jpg
Before Width: | Height: | Size: 65 KiB |
BIN
mys/bg/3.jpg
Before Width: | Height: | Size: 289 KiB |
BIN
mys/bg/4.jpg
Before Width: | Height: | Size: 706 KiB |
Before Width: | Height: | Size: 172 KiB After Width: | Height: | Size: 172 KiB |
BIN
mys/bg/default2.jpg
Normal file
After Width: | Height: | Size: 1.1 MiB |
BIN
mys/char_img/UI_AvatarIcon_Albedo@2x.png
Normal file
After Width: | Height: | Size: 614 KiB |
BIN
mys/char_img/UI_AvatarIcon_Ambor@2x.png
Normal file
After Width: | Height: | Size: 508 KiB |
BIN
mys/char_img/UI_AvatarIcon_Ayaka@2x.png
Normal file
After Width: | Height: | Size: 689 KiB |
BIN
mys/char_img/UI_AvatarIcon_Barbara@2x.png
Normal file
After Width: | Height: | Size: 530 KiB |
BIN
mys/char_img/UI_AvatarIcon_Beidou@2x.png
Normal file
After Width: | Height: | Size: 637 KiB |
BIN
mys/char_img/UI_AvatarIcon_Bennett@2x.png
Normal file
After Width: | Height: | Size: 590 KiB |
BIN
mys/char_img/UI_AvatarIcon_Diluc@2x.png
Normal file
After Width: | Height: | Size: 602 KiB |
BIN
mys/char_img/UI_AvatarIcon_Diona@2x.png
Normal file
After Width: | Height: | Size: 418 KiB |
BIN
mys/char_img/UI_AvatarIcon_Eula@2x.png
Normal file
After Width: | Height: | Size: 611 KiB |
BIN
mys/char_img/UI_AvatarIcon_Feiyan@2x.png
Normal file
After Width: | Height: | Size: 595 KiB |
BIN
mys/char_img/UI_AvatarIcon_Fischl@2x.png
Normal file
After Width: | Height: | Size: 507 KiB |
BIN
mys/char_img/UI_AvatarIcon_Ganyu@2x.png
Normal file
After Width: | Height: | Size: 516 KiB |
BIN
mys/char_img/UI_AvatarIcon_Hutao@2x.png
Normal file
After Width: | Height: | Size: 540 KiB |
BIN
mys/char_img/UI_AvatarIcon_Kaeya@2x.png
Normal file
After Width: | Height: | Size: 712 KiB |
BIN
mys/char_img/UI_AvatarIcon_Kazuha@2x.png
Normal file
After Width: | Height: | Size: 795 KiB |
BIN
mys/char_img/UI_AvatarIcon_Keqing@2x.png
Normal file
After Width: | Height: | Size: 549 KiB |
BIN
mys/char_img/UI_AvatarIcon_Klee@2x.png
Normal file
After Width: | Height: | Size: 423 KiB |
BIN
mys/char_img/UI_AvatarIcon_Lisa@2x.png
Normal file
After Width: | Height: | Size: 489 KiB |
BIN
mys/char_img/UI_AvatarIcon_Mona@2x.png
Normal file
After Width: | Height: | Size: 530 KiB |
BIN
mys/char_img/UI_AvatarIcon_Ningguang@2x.png
Normal file
After Width: | Height: | Size: 581 KiB |
BIN
mys/char_img/UI_AvatarIcon_Noel@2x.png
Normal file
After Width: | Height: | Size: 518 KiB |
BIN
mys/char_img/UI_AvatarIcon_PlayerBoy@2x.png
Normal file
After Width: | Height: | Size: 561 KiB |
BIN
mys/char_img/UI_AvatarIcon_PlayerGirl@2x.png
Normal file
After Width: | Height: | Size: 545 KiB |
BIN
mys/char_img/UI_AvatarIcon_Qin@2x.png
Normal file
After Width: | Height: | Size: 461 KiB |
BIN
mys/char_img/UI_AvatarIcon_Qiqi@2x.png
Normal file
After Width: | Height: | Size: 475 KiB |
BIN
mys/char_img/UI_AvatarIcon_Razor@2x.png
Normal file
After Width: | Height: | Size: 589 KiB |
BIN
mys/char_img/UI_AvatarIcon_Shougun@2x.png
Normal file
After Width: | Height: | Size: 916 KiB |
BIN
mys/char_img/UI_AvatarIcon_Tartaglia@2x.png
Normal file
After Width: | Height: | Size: 788 KiB |
BIN
mys/char_img/UI_AvatarIcon_Venti@2x.png
Normal file
After Width: | Height: | Size: 540 KiB |
BIN
mys/char_img/UI_AvatarIcon_Xiangling@2x.png
Normal file
After Width: | Height: | Size: 465 KiB |
BIN
mys/char_img/UI_AvatarIcon_Xiao@2x.png
Normal file
After Width: | Height: | Size: 788 KiB |
BIN
mys/char_img/UI_AvatarIcon_Xingqiu@2x.png
Normal file
After Width: | Height: | Size: 454 KiB |
BIN
mys/char_img/UI_AvatarIcon_Yoimiya@2x.png
Normal file
After Width: | Height: | Size: 656 KiB |
BIN
mys/char_img/UI_AvatarIcon_Zhongli@2x.png
Normal file
After Width: | Height: | Size: 651 KiB |
16
mys/index/lots.txt
Normal file
@ -0,0 +1,16 @@
|
||||
- 4oCU4oCU5aSn5ZCJ4oCU4oCUCuWuneWJkeWHuuWMo+adpe+8jOaXoOW+gOS4jeWIqeOAguWHuuWMo+S5i+WFie+8jOS6puiDveeFp+S6ruS7luS6uuOAggrku4rml6Xog73kuIDnrq3lsITkuK3nqbrkuK3nmoTnjI7nianvvIzog73kuIDlh7vlkb3kuK3lrojljavopoHlrrPjgIIK6Iul5rKh5pyJ55uu5qCH77yM5LiN5aao5Zub5aSE6L2s6L2s77yM6K+05LiN5a6a5Lya5pyJ5oSP5aSW5LmL5Zac44CCCuWQjOaXtu+8jOS5n+S4jeimgeW/mOiusOWSjOWAkumcieeahOWQjOS8tOWIhuS6q+S4gOS4i+Wlvei/kOawlOWTpuOAggoK5LuK5aSp55qE5bm46L+Q54mp5pivOumavuW+l+S4gOingeeahOOAjOmprOWwvuOAjeOAggrpqazlsL7pmo/lpKfniYfojbvojYnnlJ/plb/vvIzkvYbljbTmm7TkuLrmjLrmi5TjgIIK5LiO5YKy54S25oy656uL5LqO5q2k5LiW55qE5L2g5LiA5a6a5b6I5piv55u46YWN44CC
|
||||
- 4oCU4oCU5aSn5ZCJ4oCU4oCUCuWkseiAjOWkjeW+l+eahOS4gOWkqeOAggrljp/mnKzku6XkuLrnn7PmsonlpKfmtbfnmoTkuovmg4XmnInkuoblpb3nmoTlm57lupTvvIwK5Y6f5pys5YiG6YGT5oms6ZWz55qE5pyL5Y+L5oiW6K645Y+v5Lul5YaN5bqm5ZKM5aW977yMCuS4jee7j+aEj+mXtOaDs+i1t+S6huWOn+acrOW3sue7j+W/mOiusOS6hueahOS6i+aDheOAggrkuJbnlYzkuIrmsqHmnInku4DkuYjmmK/msLjov5zml6Dms5XmjL3lm57nmoTvvIwK5LuK5aSp5bCx5piv6IO95aSf5oy95Zue5aSx5Y675LqL54mp55qE5pel5a2Q44CCCgrku4rlpKnnmoTlubjov5DnianmmK865rS76Lmm5Lmx6Lez55qE44CM6ay85YWc6Jmr44CN44CCCumsvOWFnOiZq+aYr+eIseWlveWSjOW5s+OAgeS4jeaEv+aEj+S6ieaWl+eahOWwj+eUn+eJqeOAggrov5nku73ov73msYLlubPlkoznmoTlv4PkuIDlrprog73kuLrkvaDluKbmnaXlubjnpo/lkKfjgII=
|
||||
- 4oCU4oCU5aSn5ZCJ4oCU4oCUCuS8mui1t+mjjueahOaXpeWtkO+8jOaXoOiuuuW5suS7gOS5iOmDveS8muW+iOmhuuWIqeeahOS4gOWkqeOAggrlkajlm7TnmoTkurrlv4Pmg4XkuZ/pnZ7luLjmhInlv6vvvIznu53lr7nkuI3kvJrlj5HnlJ/lhrLnqoHvvIwK6L+Y5Y+v5Lul5ZCD5Yiw5LiA55u05oOz5ZCD77yM5L2G5rKh5py65Lya5ZCD55qE576O5ZGz5L2z6IK044CCCuaXoOiuuuaYr+W3peS9nO+8jOi/mOaYr+aXheihjO+8jOmDveS4gOWumuS8muWNgeWIhumhuuWIqeWQp+OAggrpgqPkuYjvvIzlupTlvZPlnKjov5nmoLfnmoTlpb3ml7bovrDph4zvvIzkuIDpvJPkvZzmsJTliY3ov5suLi4KCuS7iuWkqeeahOW5uOi/kOeJqeaYrzrojIHlo67miJDplb/nmoTjgIzpuKPojYnjgI3jgIIK6K645aSa5Lq65oiW6K645LiN55+l6YGT77yM6bij6I2J5piv6IO96aKE5oql6Zu35pq055qE5qSN54mp44CCCuWQkeW+gOedgOmbt+elnuWkp+S6uueahOmdkuedkO+8jOWPquWcqOeou+Wmu+WIl+Wym+S4iueUn+mVv+OAggrmkZjkuIvpuKPojYnml7bphaXphaXpurvpurvnmoTop6bmhJ/vvIzmja7or7Tlkozlubjnpo/nmoTmu4vlkbPlvojlg4/jgII=
|
||||
- 4oCU4oCU5aSn5ZCJ4oCU4oCUCua1ruS6keaVo+WwveaciOW9k+epuu+8jOmAouatpOetvuiAheeahuS4uuS4iuWQieOAggrmmI7plZzlnKjlv4PmuIXlpoLorrjvvIzmiYDmsYLkuYvkuovlv4Pmg7PliJnmiJDjgIIK5ZCI6YCC6aG65b+D6ICM5Li655qE5LiA5aSp77yM5LiN566h5piv5oOz5YGa55qE5LqL5oOF77yMCui/mOaYr+aDs+ingeeahOS6uu+8jOeOsOWcqOaYr+ihjOWKqOi1t+adpeeahOWlveaXtuacuuOAggoK5LuK5aSp55qE5bm46L+Q54mp5pivOuS4jeaWreWPkeeDreeahOOAjOeDiOeEsOiKseiKseiViuOAjeOAggrng4jnhLDoirHnmoTngpnng63mnaXoh6rkuo7ngavovqPovqPnmoToirHlv4PjgIIK5LiH5LqL6aG65Yip5piv5Zug5Li65b+D5Lit6Ieq5pyJ5LiA5p2h5piO6Lev44CC
|
||||
- 4oCU4oCU5Lit5ZCJ4oCU4oCUCuWNgeW5tOejqOS4gOWJke+8jOS7iuacneekuumcnOWIg+OAggrmgbbov5Dlt7LplIDvvIzouqvkuLTlkKbmnoHms7DmnaXkuYvml7bjgIIK6Ium57uD5aSa5bm05pyq6IO95LiA5pi+6Lqr5omL55qE5omN6IO977yMCueOsOS7iuacieS6huWkp+Wxlei6q+aJi+eahOaegeWlveacuuS8muOAggroi6XmmK/pgYfliLDpmLvnoo3kuYvkuovvvIzkuqbkuI3lv4Xov7fmg5jvvIwK5aSn6IOG5Zyw5ouU5YmR77yM55eb5b+r5Zyw5oiY5paX5LiA55Wq5ZCn44CCCgrku4rlpKnnmoTlubjov5DnianmmK8655Sf6ZW/5aSa5bm055qE44CM5rW354G16Iqd44CN44CCCuW8seWwj+eahOa1t+eBteiKneiZq+e7j+WOhuWkmuW5tOeahOmjjumjjumbqOmbqO+8jOaJjeiDvee7k+aIkOa1t+eBteiKneOAggrkuLrnm67moIfogIzliqrlipvliY3ooYznmoTkurrku6zvvIzmnIDnu4jkuZ/lv4XlsIbmi6XmnInog5zliKnnmoTmnpzlrp7jgII=
|
||||
- 4oCU4oCU5Lit5ZCJ4oCU4oCUCuWkqeS4iuacieS6kemjmOi/h+eahOaXpeWtkO+8jOWkqeawlOS7pOS6uuWNgeWIhuiIkueVheOAggrlt6XkvZzpnZ7luLjpobrliKnvvIzov57ljYjnnaHml7bkuZ/kvJrmg7PliLDlpb3ngrnlrZDjgIIK56qB54S25Y+R546w77yM5LiO6ICB5pyL5Y+L6L+Y5pyJ5YW25LuW55qE5YWx5ZCM6K+d6aKYLi4uCuKAlOKAlOavj+S4gOWkqeavj+S4gOWkqemDveimgeenr+aegeW8gOacl+WcsOW6pui/h+KAlOKAlAoK5LuK5aSp55qE5bm46L+Q54mp5pivOuiJsuazveiJs+S4veeahOOAjOWgh+eTnOOAjeOAggrkurrku6zluLjor7Tooajph4zlpoLkuIDmmK/nvo7lvrfvvIwK5L2G5aCH55Oc5piO6Imz55qE5aSW6LKM5LiL6ZqQ6JeP552A55qE5piv6LCm5Y2R6ICM55SY55Sc55qE5YaF5Zyo44CC
|
||||
- 4oCU4oCU5ZCJ4oCU4oCUCuS4gOWmguaXouW+gOeahOS4gOWkqeOAgui6q+S9k+WSjOW/g+eBtemDvemAguW6lOS6hueahOaXpeW4uOOAggrlh7rnjrDkuobog73mm7/ku6PlvITkuKLnmoTkuJzopb/nmoTnianlk4HvvIzku6TkurrlvojoiJLlv4PjgIIK5ZKM5bi45bi46YGH6KeB55qE5Lq65YWz57O75Lya5Y+Y5aW977yM5Y+v6IO95Lya5oiQ5Li65pyL5Y+L44CCCuKAlOKAlOaXoOiuuuaYr+WkmuWvu+W4uOeahOaXpeWtkO+8jOmDveiDveaIkOS4uuWunei0teeahOWbnuW/huKAlOKAlAoK5LuK5aSp55qE5bm46L+Q54mp5pivOumXqumXquWPkeS6rueahOOAjOaZtuaguOOAjeOAggrmmbbonbbmmK/lh53ogZrlpKnlnLDpl7TnmoTlhYPntKDvvIzogIzplb/miJDnmoTnu4blsI/nlJ/nianjgIIK6ICM5YWD57Sg5piv6L+Z5Liq5LiW55WM6K645Lul5aSp5Zyw5b2T5Lit55qE5Lq65Lus55qE56Wd56aP44CC
|
||||
- 4oCU4oCU5ZCJ4oCU4oCUCuaYjuaYjuayoeacieS7gOS5iOeJueWIq+eahOS6i+aDhe+8jOWNtOaEn+WIsOW/g+aDhei9u+W/q+eahOaXpeWtkOOAggrlnKjmsqHms6jmhI/ov4fnmoTop5LokL3lj6/ku6Xmib7liLDmnKzku6XkuLrkuKLlpLHlt7LkuYXnmoTkuJzopb/jgIIK6aOf54mp5q+U5bmz5pe25pu05Yqg6bKc576O77yM6Lev5LiK55qE6aOO5pmv5Lmf5Luk5Lq655y85YmN5LiA6auY44CCCuKAlOKAlOi/meS4quS4lueVjOS4iuWFhea7oeS6huaWsOWlh+eahOe+juWlveS6i+eJqeKAlOKAlAoK5LuK5aSp55qE5bm46L+Q54mp5pivOuaVo+WPkeaaluaEj+eahOOAjOm4n+ibi+OAjeOAggrpuJ/om4vlrZXogrLnnYDml6DpmZDnmoTlj6/og73mgKfvvIzmmK/mnKrmnaXkuYvnp43jgIIK5Y+N6L+H5p2l77yM6L+Z5Liq5LiW55WM5a+56bif6JuL5Lit55qE55Sf5ZG96ICM6KiA77yMCuS5n+WFhea7oeS6huS7pOWFtuWFtOWli+eahOacquefpeS6i+eJqeWQp+OAggropoHmuKnmn5Tlr7nlvoXpuJ/om4vllpTjgII=
|
||||
- 4oCU4oCU5ZCJ4oCU4oCUCuaer+acqOmAouaYpe+8jOato+W9k+S4h+eJqeWkjeiLj+S5i+aXtuOAggrpmbflhaXlm7DlooPml7bvvIzog73lvpfliLDop6PlhrPlip7ms5XjgIIK5Li+5qOL5LiN5a6a5pe277yM5Lya5pyJ6LS15Lq65p2l55u45Yqp44CCCuWPr+S7peaVtOmhv+S4gOeVquW/g+aDhe+8jOa4heeQhuS4gOeVquWutuijhe+8jAror7TkuI3lrprog73lj5HnjrDmhI/lpJbkuYvotKLjgIIKCuS7iuWkqeeahOW5uOi/kOeJqeaYrzroioLoioLpq5jljYfnmoTjgIznq7nnrIvjgI3jgIIK56u556yL5oul5pyJ552A5peg6ZmQ55qE5r2c5Yqb77yMCuayoeacieS6uuefpemBk+S4gOmil+erueesi++8jOWIsOW6leiDvemVv+aIkOWkmumrmOeahOerueWtkOOAggrnnIvnnYDnq7nnrIvvvIzkvJrorqnkurrkuI3nlLHoh6rkuLvmnJ/lvoXotbfmnKrmnaXlkKfjgII=
|
||||
- 4oCU4oCU5pyr5ZCJ4oCU4oCUCuawlOWOi+eojeW+ruacieeCueS9ju+8jOaYr+S8muS7pOS6uuaDs+WIsOmBpei/nOeahOi/h+WOu+eahOaXpeWtkOOAggrml6nlt7Lov4flvoDnmoTlubTovbvlsoHmnIjvvIzkuI7lho3msqHogZTns7vov4fnmoTmlYXlj4vnmoTlm57lv4bvvIwK5Lya6K6p5Lq65oSf5Yiw5Lid5bmz5reh55qE5oCA5b+177yM5Y+I56iN5b6u5pyJ5LiA54K554K55oSf5Lyk44CCCuKAlOKAlOWBtuWwlOaAgOW/tei/h+WOu+S5n+W+iOWlveOAguaUvuadvuW/g+aDhemdouWvueacquadpeWQp+KAlOKAlAoK5LuK5aSp55qE5bm46L+Q54mp5pivOua4heaWsOaAoeS6uueahOOAjOiWhOiNt+OAjeOAggrlj6ropoHmnInojYnmnKjnlJ/plb/nmoTnqbrpl7TvvIzlsLHkuIDlrprmnInoloTojbfjgIIK6L+Z5LmI55yL5p2l77yM6JaE6I235piv5LiW55WM5LiK5pyA5by66Z+n55qE55Sf54G144CCCuaNruivtOi/nuiSmeW+t+eahOmbquWxseS4iuS5n+mVv+edgOiWhOiNt+WRouOAgg==
|
||||
- 4oCU4oCU5pyr5ZCJ4oCU4oCUCuepuuS4reeahOS6keWxguWBj+S9ju+8jOW5tuS4lOS7jeacieWghuenr+S5i+WKv++8jArkuI3nn6XkvZXml7bpm7fpm6jkvJrpqqTnhLbku47lpLTpobblgL7nm4bogIzkuIvjgIIK5L2G5piv562J6Zu36Zuo6L+H5ZCO77yM6L+Y5Lya5pyJ5b2p6Jm55Zyo562J552A44CCCuWunOW+quS6juaXp++8jOWuiOS6jumdme+8jOiLpeWmhOS4uuWImemavuaIkOS5i+OAggoK5LuK5aSp55qE5bm46L+Q54mp5pivOuagkeS4iuaOieiQveeahOOAjOadvuaenOOAjeOAggrlubbkuI3mmK/miYDmnInnmoTmnb7mnpzpg73og73plb/miJDpq5jlpKfnmoTmnb7moJHvvIwK5oiQ6ZW/6ZyA6KaB6YCC5a6c55qE546v5aKD77yM5pu06ZyA6KaB5LiA54K56L+Q5rCU44CCCuaJgOS7peS4jeeUqOe7meiHquW3sei/h+WkmuWOi+WKm++8jOiAkOW/g+etieW+heW9qeiZueWQp+OAgg==
|
||||
- 4oCU4oCU5pyr5ZCJ4oCU4oCUCuS6kemBruaciOWNiui+ue+8jOmbvui1t+abtOi/t+emu+OAggrmiqzlpLTljbPmmK/mta7kupHpga7mnIjvvIzkvY7lpLTliJnmmK/mtZPpm77mvKvmvKvjgIIK6Jm954S25LiA5pe25YmN6Lev6L+35oOY77yM5L2G5Lmf5Lya5pyJ5LiA5YiH5piO5LqG55qE5pe25Yi744CCCueOsOS4i+S4jeWmgui2geatpOacuuS8muejqOeCvOiHquaIke+8jOetieW+heaLqOS6keingeeajuaciOOAggoK5LuK5aSp55qE5bm46L+Q54mp5pivOuaal+S4reWPkeS6rueahOOAjOWPkeWFiemrk+OAjeOAggrlj5HlhYnpq5PliqrlipvlnLDlj5Hlh7rlvq7lvLHnmoTlhYnoipLjgIIK6Jm954S25q+U5LiN6L+H5YW25LuW5YWJ5rqQ77yM5L2G55yL5riF5YmN6Lev5Lmf5aSf55So5LqG44CC
|
||||
- 4oCU4oCU5pyr5ZCJ4oCU4oCUCuW5s+eos+WuieivpueahOS4gOWkqeOAguayoeacieS7gOS5iOS7pOS6uumavui/h+eahOS6i+aDheS8muWPkeeUn+OAggrpgILlkIjlkozkuYXmnKrogZTns7vnmoTmnIvlj4vogYrogYrov4fljrvnmoTkuovmg4XvvIzkuIDlkIzmrKLnrJHjgIIK5ZCD5Lic6KW/55qE5pe25YCZ5Lya5bCd5Yiw5b6I5LmF5Lul5YmN5L2T6aqM6L+H55qE6L+H5Y6755qE5ZGz6YGT44CCCuKAlOKAlOimgeePjeaDnOi6q+i+ueeahOS6uuS4juS6i+KAlOKAlAoK5LuK5aSp55qE5bm46L+Q54mp5pivOumFpemFpem6u+m6u+eahOOAjOeUteawlOawtOaZtuOAjeOAggrnlLXmsJTmsLTmmbbolbTlkKvnnYDml6DpmZDnmoTog73ph4/jgIIK5aaC5p6c6IO95aSf5aW95aW95a+85byV6L+Z6IKh6IO96YeP77yM6K+05LiN5a6a5bCx6IO95oiQ5bCx5LuA5LmI5LqL5Lia44CC
|
||||
- 4oCU4oCU5Ye24oCU4oCUCumakOe6puaEn+inieS8muS4i+mbqOeahOS4gOWkqeOAguWPr+iDveS8mumBh+WIsOS4jemhuuW/g+eahOS6i+aDheOAggrlupTor6XnmoTopJLlpZbov5/ov5/msqHmnInliLDmnaXvvIzmnI3liqHnlJ/kuZ/lj6/og73kvJrkuIrplJnoj5zjgIIK5piO5piO5rKh5LuA5LmI5aSn5LiN5LqG55qE5LqL77yM5Y205oC75oSf6KeJ5pyJ5Lqb5b+D54Om55qE5pel5a2Q44CCCuKAlOKAlOmavuWFjeaciei/meagt+eahOaXpeWtkOKAlOKAlAoK5LuK5aSp55qE5bm46L+Q54mp5pivOumaj+azouaRh+abs+eahOOAjOa1t+iNieOAjeOAggrmtbfojYnmmK/nm7jlvZPmuKnmn5TogIzlnZrlvLrnmoTmpI3nianvvIwK5Y2z5L2/5Zyo6Ium5rap55qE5rW35rC05Lit77yM5Lmf5LiN5oS/5pS55Y+Y6Ieq5bex44CCCuWNs+S9v+WcqOmAhuWig+S4re+8jOS5n+S4jeimgeaUvuW8g+a4qeaflOeahOW/g+eBteOAgg==
|
||||
- 4oCU4oCU5Ye24oCU4oCUCuePjeaDnOeahOS4nOilv+WPr+iDveS8mumBl+Wkse+8jOmcgOimgeWwj+W/g+OAggrlpoLmnpzouqvkvZPmnInkuI3pgILvvIzkuIDlrpropoHms6jmhI/kvJHmga/jgIIK5Zyo5YGa5Ye65Yaz5a6a5LmL5YmN77yM5LiA5a6a6KaB5YaN5LiJ5oCd6ICD44CCCgrku4rlpKnnmoTlubjov5DnianmmK865Yaw5YeJ5Yaw5YeJ55qE44CM5Yaw6Zu+6Iqx44CN44CCCuWGsOmbvuiKseaVo+WPkeedgOOAjOeUn+S6uuWLv+i/m+OAjeeahOWvkuawlOOAggrkvYbmnInml7blhrDlhrfnmoTmsJTotKjvvIzkuZ/og73orqnkurrnmoTlv4Pmg4XkuI7lpLTohJHlhrfpnZnkuIvmnaXjgIIK5o2u5q2k6YeH5Y+W5q2j56Gu55qE5Yik5pat77yM5piO5pm65Zyw6KGM5Yqo44CC
|
||||
- 4oCU4oCU5aSn5Ye24oCU4oCUCuWGheW/g+epuuiQveiQveeahOS4gOWkqeOAguWPr+iDveS8mumZt+WFpea3sea3seeahOaXoOWKm+aEn+S5i+S4reOAggrlvojlpJrkuovmg4Xpg73ml6Dms5XnkIbmuIXlpLTnu6rvvIzov4fkuo7pkrvniZvop5LlsJbliJnmmJPnlJ/nl4XjgIIK6Jm954S25LiA5YiH55qG6Zm35LqO5L2O5r2u6LC35bqV5Lit77yM5L2G5Lmf5LiN5b+F5Zug5q2k6ICM5rCU6aaB44CCCuiLpeiDveaSkei/h+S4gOaXtuWbsOWig++8jOS7luaXpeW/heWPpuacieS4gOeVquS9nOS4uuOAggoK5LuK5aSp55qE5bm46L+Q54mp5pivOuW8r+W8r+absuabsueahOOAjOicpeictOWwvuW3tOOAjeOAggronKXonLTpgYfliLDmvZzlnKjnmoTljbHpmanml7bvvIzlpKflpJrmlbDkvJrmlq3lsL7msYLnlJ/jgIIK6Iul5piv6YGH5Yiw5peg5rOV5pW055CG55qE5oOF57uq77yM6YKj5LmI6K+l5pat5YiZ5pat5ZCn44CC
|
BIN
mys/reliquaries/UI_RelicIcon_10005_1.png
Normal file
After Width: | Height: | Size: 57 KiB |
BIN
mys/reliquaries/UI_RelicIcon_10009_4.png
Normal file
After Width: | Height: | Size: 62 KiB |
BIN
mys/reliquaries/UI_RelicIcon_14001_1.png
Normal file
After Width: | Height: | Size: 73 KiB |
BIN
mys/reliquaries/UI_RelicIcon_14001_2.png
Normal file
After Width: | Height: | Size: 78 KiB |
BIN
mys/reliquaries/UI_RelicIcon_14001_3.png
Normal file
After Width: | Height: | Size: 79 KiB |
BIN
mys/reliquaries/UI_RelicIcon_14001_4.png
Normal file
After Width: | Height: | Size: 91 KiB |
BIN
mys/reliquaries/UI_RelicIcon_14001_5.png
Normal file
After Width: | Height: | Size: 102 KiB |
BIN
mys/reliquaries/UI_RelicIcon_14002_3.png
Normal file
After Width: | Height: | Size: 74 KiB |
BIN
mys/reliquaries/UI_RelicIcon_14002_4.png
Normal file
After Width: | Height: | Size: 102 KiB |
BIN
mys/reliquaries/UI_RelicIcon_14003_1.png
Normal file
After Width: | Height: | Size: 78 KiB |
BIN
mys/reliquaries/UI_RelicIcon_14003_2.png
Normal file
After Width: | Height: | Size: 71 KiB |
BIN
mys/reliquaries/UI_RelicIcon_14003_3.png
Normal file
After Width: | Height: | Size: 79 KiB |
BIN
mys/reliquaries/UI_RelicIcon_14003_4.png
Normal file
After Width: | Height: | Size: 83 KiB |
BIN
mys/reliquaries/UI_RelicIcon_14003_5.png
Normal file
After Width: | Height: | Size: 93 KiB |
BIN
mys/reliquaries/UI_RelicIcon_14004_1.png
Normal file
After Width: | Height: | Size: 86 KiB |
BIN
mys/reliquaries/UI_RelicIcon_14004_2.png
Normal file
After Width: | Height: | Size: 69 KiB |
BIN
mys/reliquaries/UI_RelicIcon_14004_3.png
Normal file
After Width: | Height: | Size: 83 KiB |
BIN
mys/reliquaries/UI_RelicIcon_14004_4.png
Normal file
After Width: | Height: | Size: 95 KiB |
BIN
mys/reliquaries/UI_RelicIcon_14004_5.png
Normal file
After Width: | Height: | Size: 81 KiB |
BIN
mys/reliquaries/UI_RelicIcon_15001_1.png
Normal file
After Width: | Height: | Size: 77 KiB |
BIN
mys/reliquaries/UI_RelicIcon_15001_2.png
Normal file
After Width: | Height: | Size: 67 KiB |
BIN
mys/reliquaries/UI_RelicIcon_15001_3.png
Normal file
After Width: | Height: | Size: 85 KiB |
BIN
mys/reliquaries/UI_RelicIcon_15001_4.png
Normal file
After Width: | Height: | Size: 83 KiB |
BIN
mys/reliquaries/UI_RelicIcon_15001_5.png
Normal file
After Width: | Height: | Size: 84 KiB |
BIN
mys/reliquaries/UI_RelicIcon_15002_1.png
Normal file
After Width: | Height: | Size: 80 KiB |
BIN
mys/reliquaries/UI_RelicIcon_15002_2.png
Normal file
After Width: | Height: | Size: 63 KiB |
BIN
mys/reliquaries/UI_RelicIcon_15002_3.png
Normal file
After Width: | Height: | Size: 77 KiB |
BIN
mys/reliquaries/UI_RelicIcon_15002_4.png
Normal file
After Width: | Height: | Size: 86 KiB |
BIN
mys/reliquaries/UI_RelicIcon_15002_5.png
Normal file
After Width: | Height: | Size: 82 KiB |
BIN
mys/reliquaries/UI_RelicIcon_15003_1.png
Normal file
After Width: | Height: | Size: 79 KiB |
BIN
mys/reliquaries/UI_RelicIcon_15003_2.png
Normal file
After Width: | Height: | Size: 73 KiB |
BIN
mys/reliquaries/UI_RelicIcon_15003_3.png
Normal file
After Width: | Height: | Size: 77 KiB |
BIN
mys/reliquaries/UI_RelicIcon_15003_4.png
Normal file
After Width: | Height: | Size: 80 KiB |
BIN
mys/reliquaries/UI_RelicIcon_15003_5.png
Normal file
After Width: | Height: | Size: 78 KiB |
BIN
mys/reliquaries/UI_RelicIcon_15005_1.png
Normal file
After Width: | Height: | Size: 67 KiB |
BIN
mys/reliquaries/UI_RelicIcon_15005_2.png
Normal file
After Width: | Height: | Size: 64 KiB |
BIN
mys/reliquaries/UI_RelicIcon_15005_4.png
Normal file
After Width: | Height: | Size: 94 KiB |
BIN
mys/reliquaries/UI_RelicIcon_15005_5.png
Normal file
After Width: | Height: | Size: 93 KiB |
BIN
mys/reliquaries/UI_RelicIcon_15006_1.png
Normal file
After Width: | Height: | Size: 87 KiB |
BIN
mys/reliquaries/UI_RelicIcon_15006_2.png
Normal file
After Width: | Height: | Size: 87 KiB |
BIN
mys/reliquaries/UI_RelicIcon_15006_3.png
Normal file
After Width: | Height: | Size: 89 KiB |
BIN
mys/reliquaries/UI_RelicIcon_15006_4.png
Normal file
After Width: | Height: | Size: 96 KiB |
BIN
mys/reliquaries/UI_RelicIcon_15006_5.png
Normal file
After Width: | Height: | Size: 99 KiB |
BIN
mys/reliquaries/UI_RelicIcon_15007_1.png
Normal file
After Width: | Height: | Size: 82 KiB |
BIN
mys/reliquaries/UI_RelicIcon_15007_2.png
Normal file
After Width: | Height: | Size: 72 KiB |
BIN
mys/reliquaries/UI_RelicIcon_15007_3.png
Normal file
After Width: | Height: | Size: 74 KiB |
BIN
mys/reliquaries/UI_RelicIcon_15007_4.png
Normal file
After Width: | Height: | Size: 79 KiB |
BIN
mys/reliquaries/UI_RelicIcon_15007_5.png
Normal file
After Width: | Height: | Size: 78 KiB |
BIN
mys/reliquaries/UI_RelicIcon_15008_4.png
Normal file
After Width: | Height: | Size: 84 KiB |
BIN
mys/reliquaries/UI_RelicIcon_15008_5.png
Normal file
After Width: | Height: | Size: 91 KiB |
BIN
mys/reliquaries/UI_RelicIcon_15014_1.png
Normal file
After Width: | Height: | Size: 74 KiB |
BIN
mys/reliquaries/UI_RelicIcon_15014_2.png
Normal file
After Width: | Height: | Size: 63 KiB |
BIN
mys/reliquaries/UI_RelicIcon_15014_3.png
Normal file
After Width: | Height: | Size: 75 KiB |
BIN
mys/reliquaries/UI_RelicIcon_15014_4.png
Normal file
After Width: | Height: | Size: 85 KiB |
BIN
mys/reliquaries/UI_RelicIcon_15014_5.png
Normal file
After Width: | Height: | Size: 62 KiB |
BIN
mys/reliquaries/UI_RelicIcon_15015_2.png
Normal file
After Width: | Height: | Size: 87 KiB |