From 64c82d9d7981276759926d9e0524153a45767bc0 Mon Sep 17 00:00:00 2001 From: KimigaiiWuyi <444835641@qq.com> Date: Sun, 7 Jan 2024 04:53:47 +0800 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20=E6=96=B0=E5=A2=9E`=E8=A7=92?= =?UTF-8?q?=E8=89=B2=E6=8E=92=E5=90=8D=E5=85=AC=E5=AD=90`,=20=E5=8E=9F?= =?UTF-8?q?=E5=85=88=E7=9A=84`=E8=A7=92=E8=89=B2=E6=8E=92=E5=90=8D`?= =?UTF-8?q?=E8=BF=81=E7=A7=BB=E8=87=B3`=E8=A7=92=E8=89=B2=E6=8E=92?= =?UTF-8?q?=E8=A1=8C=E6=A6=9C`?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- GenshinUID/genshinuid_enka/__init__.py | 30 +++++- GenshinUID/genshinuid_enka/draw_role_rank.py | 86 +++++++++++++----- .../genshinuid_enka/texture2D/rank_img/sp.png | Bin 0 -> 2492 bytes GenshinUID/utils/api/cv/api.py | 4 +- GenshinUID/utils/api/cv/request.py | 46 +++++++--- 5 files changed, 130 insertions(+), 36 deletions(-) create mode 100644 GenshinUID/genshinuid_enka/texture2D/rank_img/sp.png diff --git a/GenshinUID/genshinuid_enka/__init__.py b/GenshinUID/genshinuid_enka/__init__.py index d194b756..e9dc9b1b 100644 --- a/GenshinUID/genshinuid_enka/__init__.py +++ b/GenshinUID/genshinuid_enka/__init__.py @@ -61,8 +61,24 @@ async def sned_rank_pic(bot: Bot, ev: Event): ) -@sv_akasha.on_prefix('角色排名') +@sv_akasha.on_prefix('角色排行榜') async def sned_role_rank_pic(bot: Bot, ev: Event): + # 获取角色名 + msg = ''.join(re.findall('[\u4e00-\u9fa5 ]', ev.text)) + if not msg: + return + logger.info(f'[角色排行榜]角色: {msg}') + a = Button('💖排名列表', '排名列表') + b = Button(f'✅查询{msg}', f'查询{msg}') + c = Button(f'💖角色排名{msg}', f'角色排名{msg}') + d = Button('✅圣遗物排名', '圣遗物排名') + + im = await draw_role_rank_img(msg) + await bot.send_option(im, [a, c, b, d]) + + +@sv_akasha.on_prefix('角色排名') +async def sned_my_role_rank_pic(bot: Bot, ev: Event): # 获取角色名 msg = ''.join(re.findall('[\u4e00-\u9fa5 ]', ev.text)) if not msg: @@ -70,7 +86,17 @@ async def sned_role_rank_pic(bot: Bot, ev: Event): logger.info(f'[角色排名]角色: {msg}') a = Button('💖排名列表', '排名列表') b = Button(f'✅查询{msg}', f'查询{msg}') - await bot.send_option(await draw_role_rank_img(msg), [a, b]) + c = Button(f'💖角色排行榜{msg}', f'角色排行榜{msg}') + d = Button('✅圣遗物排名', '圣遗物排名') + + msg = msg.replace('附近', '') + # 获取uid + uid = await get_uid(bot, ev) + if uid is None: + return await bot.send(UID_HINT) + + im = await draw_role_rank_img(msg, uid) + await bot.send_option(im, [a, c, b, d]) @sv_akasha.on_command('圣遗物排名') diff --git a/GenshinUID/genshinuid_enka/draw_role_rank.py b/GenshinUID/genshinuid_enka/draw_role_rank.py index 0e8acf90..5177c1de 100644 --- a/GenshinUID/genshinuid_enka/draw_role_rank.py +++ b/GenshinUID/genshinuid_enka/draw_role_rank.py @@ -1,26 +1,28 @@ -from typing import Union +from typing import Union, Optional from PIL import Image, ImageDraw from gsuid_core.utils.image.convert import convert_img from ..utils.colors import get_color from .draw_rank_list import RANK_TEXT +from .get_akasha_data import _get_rank from ..utils.api.cv.request import _CvApi from ..utils.map.GS_MAP_PATH import icon2Name from ..genshinuid_config.gs_config import gsconfig from ..utils.resource.RESOURCE_PATH import REL_PATH, CHAR_PATH from ..utils.map.name_covert import name_to_avatar_id, alias_to_char_name -from ..utils.fonts.genshin_fonts import ( - gs_font_18, - gs_font_20, - gs_font_26, - gs_font_30, -) from ..utils.image.image_tools import ( get_talent_pic, draw_pic_with_ring, get_weapon_affix_pic, ) +from ..utils.fonts.genshin_fonts import ( + gs_font_18, + gs_font_20, + gs_font_24, + gs_font_26, + gs_font_30, +) is_enable_akasha = gsconfig.get_config('EnableAkasha').data @@ -36,21 +38,39 @@ REGION_MAP = { grey = (170, 170, 170) -async def draw_role_rank_img(char_name: str) -> Union[str, bytes]: +async def draw_role_rank_img( + char_name: str, player_uid: Optional[str] = None +) -> Union[str, bytes]: if not is_enable_akasha: return '未开启排名系统...' cv_api = _CvApi() char_name = await alias_to_char_name(char_name) char_id = await name_to_avatar_id(char_name) - raw_data = await cv_api.get_sort_list(char_id) + + if player_uid: + rank_data = await _get_rank(player_uid) + if isinstance(rank_data, str): + return rank_data + if char_id not in rank_data: + return f'你还暂无{char_name}的数据, 请先[强制刷新]...' + + fit = rank_data[char_id]['calculations']['fit'] + calculation_id = fit['calculationId'] + r0 = int(fit["result"]) + r1 = int(r0 * 1.00005) + raw_data = await cv_api.get_sort_list(char_id, calculation_id, r1) + tag = '角色附近' + else: + raw_data = await cv_api.get_sort_list(char_id) + tag = '前20' if raw_data is None: return '该角色尚未有排名...' data, count = raw_data - img = Image.open(RANK_TEXT / 'deep_grey.jpg') + img = Image.open(RANK_TEXT / 'deep_grey.jpg').resize((950, 2450)) title = Image.open(RANK_TEXT / 'title.png') user_pic = await draw_pic_with_ring( Image.open(CHAR_PATH / f'{char_id}.png'), 314 @@ -59,19 +79,35 @@ async def draw_role_rank_img(char_name: str) -> Union[str, bytes]: img.paste(title, (0, 0), title) img_draw = ImageDraw.Draw(img) - img_draw.text((475, 425), f'前20 / 总数据 {count}条', 'white', gs_font_26, 'mm') + img_draw.text( + (475, 425), f'{tag} / 总数据 {count}条', 'white', gs_font_26, 'mm' + ) + rank = 0 for index, char in enumerate(data): - if index % 2 == 0: + region: str = char['owner']['region'] + nickname: str = char['owner']['nickname'] + + if index == 0: + _rank: str = char['index'] + rank = ( + int(_rank[1:]) + if isinstance(_rank, str) and _rank.startswith('~') + else int(_rank) + ) + else: + rank += 1 + + uid: str = char['uid'] + + char_c = 'white' + if player_uid and player_uid == uid: + bar = Image.open(RANK_TEXT / 'sp.png') + elif index % 2 == 0: bar = Image.open(RANK_TEXT / 'white.png') else: bar = Image.open(RANK_TEXT / 'black.png') - bar_draw = ImageDraw.Draw(bar) - - region: str = char['owner']['region'] - nickname: str = char['owner']['nickname'] - uid: str = char['uid'] _c: int = char['constellation'] _wc: int = char['weapon']['weaponInfo']['refinementLevel']['value'] + 1 hp: int = int(char['stats']['maxHp']['value']) @@ -103,10 +139,18 @@ async def draw_role_rank_img(char_name: str) -> Union[str, bytes]: else: icon_list.append(icon_img.resize((51, 51))) - bar_draw.rounded_rectangle((47, 30, 150, 70), 10, region_color) - bar_draw.text((99, 50), region, 'white', gs_font_30, 'mm') + x1, x2 = 15, 64 + 15 * len(str(rank)) + x3 = int((x1 + x2) / 2) - bar_draw.text((162, 41), nickname, 'white', gs_font_26, 'lm') + bar_draw = ImageDraw.Draw(bar) + + bar_draw.rounded_rectangle((x1, 0, x2, 25), 9, (96, 33, 109)) + bar_draw.text((x3 + 1, 13), f'#{rank}名', 'white', gs_font_24, 'mm') + + bar_draw.rounded_rectangle((47, 35, 150, 75), 10, region_color) + bar_draw.text((99, 55), region, 'white', gs_font_30, 'mm') + + bar_draw.text((162, 41), nickname, char_c, gs_font_26, 'lm') bar_draw.text((162, 66), f'UID {uid}', grey, gs_font_20, 'lm') bar_draw.text((398, 42), f'{cr}: {cd}', 'white', gs_font_26, 'lm') bar_draw.text((398, 66), f'{cv} cv', cv_color, gs_font_20, 'lm') @@ -127,7 +171,7 @@ async def draw_role_rank_img(char_name: str) -> Union[str, bytes]: bar_draw.text((370, 67), text, (214, 255, 192), gs_font_20, 'mm') - img.paste(bar, (0, 475 + index * 90), bar) + img.paste(bar, (0, 475 + index * 95), bar) img_draw.text( (475, img.size[1] - 35), diff --git a/GenshinUID/genshinuid_enka/texture2D/rank_img/sp.png b/GenshinUID/genshinuid_enka/texture2D/rank_img/sp.png new file mode 100644 index 0000000000000000000000000000000000000000..d46c635adb527052f1242f0d27f0e9201c708d41 GIT binary patch literal 2492 zcmb7FX;70%8jcqzA}*tX+#{~yF0hK+U_gdTRA6u<4nYYhhlYf3Moyu05D=7cT@X+X zMMZN!022tO%1tCFf;mZ)02z*eTnQwGY{#vs+O6HKt?eIQ_t*9G^FHss2tt#MKH%{0GrVVjtJb!>x)Agso&*lghZx;xpHh=rqkS!3% zws0>um$QjMqS4Vw5cy;4- zIhXW3s{+l5{v&sXP7VuCoW!*`h+u&FzYImVRjY`}W`>ws1xcdT$MK{ZWe|47Ay}VB#x)e3Pgoz8U9T23= z%(P+>xbCZF>Aid5d6MZk-tyPnFS-M#7;)731uYSDtw@jn{g`j@q?XPxZtuC8ye@UM z)k|}1{ZO;+9AK*=vg@(N)e?miY#2UGqQCTb-4#9@WBypy1~XceM9J!1lWGb@mSoft zHMcM>sEZL-U?!DuB&%8zD^!O&PTj*@7MKT@_)GJ&KMy2iYpuwsSI(E-CTpDKtQCk* zO*NF6WDV{*ul2#X%ceo5;kM5>usL>LNR&_%9<@@W&;)TR(T!-iV;MT=yC^<{*%>E{ ziK_ZQG;X*kX)4>;pg2Kbm|p9zfc9O6(h_g0vu^tu+enNlMsBkcZKBkc5^V@1WA1FT z;lyE?PNSzP3oT=jF|iRh=aT0*Z(qr!U&nsotS>iS40MsD87kJSF8Aov&g9oeI^RzG zYfN)km=**Q{765dS6=LwvU(27#h>oa8&%`-Eu-7@Bzqd=`U&5WovSB4+b(wXW?!IH zjLOZ%u5_c#*&87cQe$11Ak0I=aWFO?C=!7Qd*{^er7#&=k|wcpdp1BI zdyC+$a*=oELJhU`PGUSafs4KRg!UnSF!HH5rjvJ0hn(^kHBh)m;uG$^;EVT*)9G(h z3rg>kIipwl(D+z!fzy5MTP3NPgB?>RiO&J@XSEURNMbW9S;$HqxyH)4r*&GO2;$ld zHJVl3D@vr4wexeBsn=qpwcpT&BZ-6cE0p>*oE*0yf?ds};AwqGw8lF7Pra2U_EhfI z)8-J!tHl=|@soHlUgfP;%XxBX*?Z1$PujBxGQ3%P;Zs0VArkmf2(w0z5!S)v;1sm+ z54fke%@_%67+;uNY-fE!PTXW%8s)zzMT5B+%yJ?l|JY zjEY~(Y*Fq#_S&TZMVT`|r4UGcb)v3O8#kq^Hx8nd$+ZgE4m4D33j|v#-b{cxa`_D? z#|)QU%C@CmLIMd3e)kKA@b5=ndW1NZ@c{C8;O#e9t5yKWpy-y}LX9ZTiFI!h{grI& zxP?Pt(v3{XX6$aPMEt5^syt8M*17eFW-@bOyHtzl~GY&2eGgsiX5@|JdXiUacHy9 zV0B|!jAF*(LxF+-xD4Y%KH{HPV1` zrK<2D-($9&?sZ`nWGy(yU*^9Fw%w;z7NG%yMk-;clRvM*RI6 zOv6p-zN)5_Fu7R-$tdQFal<5817se7`*s`gTR4&0l=|xea+Xl_7c7HX4`DMfy=luisr7a;<`3?F}i|BOM{Hz>Ap;J}Nh zqt&^=@}hldZN=?L`U{`%*@wjr=tv+;_xW=>)I>kk$w#6mYUM^~&9krRdg1 zOeuTskK)1oK`n19i(%Z^n0`Uzxw`dlYHwl*8oaGU?1w zS{i4q(Xs&e)a0+7>Clf5TL$GHz3406@53Lb=W*271M2LWlz^wLxc18Y^dcVh*|ha0 zTN~vg*ZtI`#o8E^dFMsK=c^;U z@C`5&MxCpB4!x&tPjfw*qA)~;H7cfJ@3B(i$|cWNWXTL+xx{X6F_kFf6+9Z~m|3q5 zOY&}tE@$9!8Inu+7Bv=PdBC)6Rq=AGAmAkHFj}Vl4_I&x45i_CGB7@t_9||W;W*~1uaQ`6$U(E#AeUW z^fWmLAGKkk5w24Gb_}6mAVg=qRN8*ipM1JpzO$HCr+APaag8hphpH+&)_)$+o|+2P XQY$mUZu{4ZN{E-ck6ZN*!Pox|JbJ8b literal 0 HcmV?d00001 diff --git a/GenshinUID/utils/api/cv/api.py b/GenshinUID/utils/api/cv/api.py index d500f232..ba4fe0f1 100644 --- a/GenshinUID/utils/api/cv/api.py +++ b/GenshinUID/utils/api/cv/api.py @@ -6,9 +6,9 @@ DATA_API = BASE + '/user/{}' REFRESH_API = BASE + '/user/refresh/{}' LEADERBOARD_API = BASE + '/v2/leaderboards/categories?characterId={}' -SORT_PROMOT = 'sort=calculation.result&' +SORT_PROMOT = 'sort=calculation.result' UNI_PROMOT = 'order=-1&size=20&page=1&filter=&uids=&fromId=' SORT_API = ( - BASE + '/leaderboards?' + SORT_PROMOT + 'p=&calculationId={}&' + UNI_PROMOT + BASE + '/leaderboards?' + SORT_PROMOT + '&calculationId={}&' + UNI_PROMOT ) ARTI_SORT_API = BASE + '/artifacts?sort={}&p=&' + UNI_PROMOT diff --git a/GenshinUID/utils/api/cv/request.py b/GenshinUID/utils/api/cv/request.py index 5d91a056..2b5ec4e2 100644 --- a/GenshinUID/utils/api/cv/request.py +++ b/GenshinUID/utils/api/cv/request.py @@ -105,18 +105,42 @@ class _CvApi: ) async def get_sort_list( - self, char_id: str + self, + char_id: str, + calculation_id: Optional[str] = None, + combo: Optional[Union[str, int]] = None, ) -> Optional[Tuple[List[Dict], int]]: - _raw_data = await self.get_calculation_info(char_id) - if _raw_data is not None: - calculation_id, count = _raw_data - raw_data = await self._cv_request( - SORT_API.format(calculation_id), - 'GET', - self._HEADER, - ) - if isinstance(raw_data, Dict) and 'data' in raw_data: - return raw_data['data'], count + count = 0 + if calculation_id is None: + _raw_data = await self.get_calculation_info(char_id) + if _raw_data is not None: + calculation_id, count = _raw_data + else: + lb_data = await self.get_leaderboard_id_list(char_id) + if lb_data: + for i in lb_data: + for g in i['weapons']: + if g['calculationId'] == calculation_id: + count = i['count'] + break + + if count == 0: + return None + + extra = '' + if combo: + extra += f'&p=lt%7C{combo}' + else: + extra = '&p=' + + url = SORT_API.format(calculation_id) + extra + raw_data = await self._cv_request( + url, + 'GET', + self._HEADER, + ) + if isinstance(raw_data, Dict) and 'data' in raw_data: + return raw_data['data'], count async def get_session_id(self) -> str: async with self.session.get(MAIN_API) as resp: