├── CAT.TTF
├── README.md
├── account.json
├── image
├── haha.png
└── 救命.png
├── pjprofile.png
├── pjskinfo.py
├── test.png
├── test1.png
├── text.png
└── zzaw.ttf
/CAT.TTF:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FLAG250/hoshino-plugin-pjsk/13ecea83d2bdb3ef1bf5fbecc2f0e4a08a88d822/CAT.TTF
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # SBGA还我API!!
2 | 鉴于unibot以开源 直接开摆(安静地躺平)
3 |
4 | # hoshino-pjsk-plugin
5 | 因为频道里的pjsk查询没有开源 翻了翻pjsk信息网站发现有api于是决定自己做
6 | 指令 `/pjsk绑定+pjskID`可以绑定发送者的qq与pjsk,
7 | 指令`/pjsk进度`可以查询master难度的完成情况
8 | 指令`/pjskpf`可以查询pjsk个人档案(目前只有各难度的clear、FC、AP完成情况,以及各个角色等级)
9 | 指令`/sk`可以查询个人当前活动分数和上一级的分数线
10 | '/pjsk进度、pjskpf' 支持可以通过@已绑定的群友或后接pjskID逮捕群友!*后接pjskID更新于20220625,前者是已有的功能*
11 |
12 | python初学者 第一次写hoshino的插件
13 | 所以你将可以在py文件中看到:屎山、多段重复代码、莫名其妙的变量名称……
14 |
15 |
16 | ## 部署方法
17 | 1.git本项目 将文件夹放在\hoshino\modulus\下
18 | 2.在\config\_bot_.py中加入“hoshino-pjsk-plugin”,
19 | 3.在pjskinfo.py中修改load_path的路径(指向你放本插件的目录)
20 | 例load_path = "C:\\Users\\Administrater\\Desktop\\haru-bot-setup\\hoshino\\modules\\hoshino-pjsk-plugin"
21 | 4.重启并运行hoshino
22 | 运行前最好在account.json里先加上你自己的qqID和pjsk信息
23 | (因为没试过空文件测试 不知道会有什么问题)
24 |
25 | ## 未来功能
26 | 谱面查询
27 | 歌曲查询
28 | 猜歌(谱面猜歌,曲绘猜歌,歌曲切片猜歌)
29 | 按歌曲别称检索
30 | (向频道的unibot靠拢)
31 | 大部分bug打算随新功能加入一起修复
32 |
33 | unibot开源了就开摆?(bushi)
34 | 会找时间整合功能减少服务器负担(自己挂的bot已经反向了4个了)
35 |
36 | ## 已知问题
37 | ~~文件中字体均不支持中日文字混用因此可能会出现下面这种情况~~(换字体后已修)
38 | >
39 | ~~由于ID过长导致:~~(已修)
40 | > 
41 | > (笑死)
42 |
43 |
44 | 每次更新活动需重启一次hoshino,原因应该是插件在开头获取一次的活动资源为静态缓存在本地)
45 |
--------------------------------------------------------------------------------
/account.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "qqid": [qq号],
4 | "pjskid": [pjskid]
5 | }
6 | ]
--------------------------------------------------------------------------------
/image/haha.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FLAG250/hoshino-plugin-pjsk/13ecea83d2bdb3ef1bf5fbecc2f0e4a08a88d822/image/haha.png
--------------------------------------------------------------------------------
/image/救命.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FLAG250/hoshino-plugin-pjsk/13ecea83d2bdb3ef1bf5fbecc2f0e4a08a88d822/image/救命.png
--------------------------------------------------------------------------------
/pjprofile.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FLAG250/hoshino-plugin-pjsk/13ecea83d2bdb3ef1bf5fbecc2f0e4a08a88d822/pjprofile.png
--------------------------------------------------------------------------------
/pjskinfo.py:
--------------------------------------------------------------------------------
1 | import json, base64, time
2 | import requests as req
3 | import os
4 | from PIL import Image, ImageDraw, ImageFont, ImageFilter
5 | import re
6 | from io import BytesIO
7 | import codecs
8 |
9 | from hoshino.typing import CQEvent, MessageSegment
10 | from hoshino import Service, priv, config
11 |
12 | import asyncio
13 |
14 | sv = Service(
15 | name = 'pjsk信息查询', #功能名
16 | use_priv = priv.NORMAL, #使用权限
17 | manage_priv = priv.SUPERUSER, #管理权限
18 | visible = False, #False隐藏
19 | enable_on_default = True, #是否默认启用
20 | bundle = '娱乐', #属于哪一类
21 | )
22 |
23 |
24 | headers = {'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.0.0 Safari/537.36'}
25 | url_getmD = 'https://musics.pjsekai.moe/musicDifficulties.json'
26 | url_getmc = 'https://musics.pjsekai.moe/musics.json'
27 | url_e_data = 'https://database.pjsekai.moe/events.json'
28 | color={"ap":"#d89aef","fc":"#ef8cee","clr":"#f0d873","all":"#6be1d9"}
29 | load_path = os.path.dirname(__file__) #更改为自动获取
30 |
31 | def data_req(url): #现场请求相关数据,耗时较长,但是数据永远是最新的
32 | temp_res = req.get(url, headers = headers)
33 | re = json.loads(temp_res.text)
34 | return re
35 |
36 | def a_check(uid,account): #bot, ev: CQEvent
37 | n_a = len(account)
38 | for a in range(n_a):
39 | if uid != account[a]["qqid"]:
40 | continue
41 | else:
42 | return False
43 | else:
44 | return True
45 |
46 | @sv.on_prefix("/pjsk绑定")
47 | async def reg(bot, ev: CQEvent):
48 | ppid = ev.message.extract_plain_text().strip()
49 | try:
50 | pid = int(ppid)
51 | uid = ev.user_id
52 | print(pid)
53 | if isinstance(pid,int) and pid > 1000000000000000: #待优化
54 | with open(load_path+f"\\account.json","r") as f:
55 | account = json.load(f)
56 | n_a = len(account)
57 |
58 | if a_check(uid,account):
59 | indexdata = []
60 | for a in range(n_a):
61 | uuid = account[a]["qqid"]
62 | ppid = account[a]["pjskid"]
63 | account_dict = {'qqid' : uuid,
64 | 'pjskid' : ppid}
65 | indexdata.append(account_dict)
66 | account_dict = {'qqid' : uid,
67 | 'pjskid' : int(pid)}
68 | indexdata.append(account_dict)
69 |
70 | with open (load_path+'\\account.json', 'w', encoding='utf8') as f:
71 | json.dump(indexdata, f,indent =2, ensure_ascii=False)
72 |
73 | await bot.send(ev,f"绑定完成!",at_sender = True)
74 | else:
75 | await bot.send(ev,f"你已经绑定过!",at_sender = True)
76 | else:
77 | await bot.send(ev,f"UID格式错误",at_sender = True)
78 | except:
79 | await bot.send(ev,f"绑定发生错误",at_sender = True)
80 |
81 |
82 |
83 |
84 |
85 |
86 | async def lg(user_id):
87 | uid = user_id
88 |
89 | with open(load_path+f'\\account.json', 'r') as fff:
90 | udata = json.load(fff)
91 | if not a_check(uid,udata):
92 | for a in udata:
93 | if uid == a['qqid']:
94 | return a['pjskid']
95 | else:
96 | continue
97 | else:
98 | return 0
99 |
100 |
101 |
102 |
103 | async def getLeaderIcon(data1):
104 | leaderId = data1['userDecks'][0]["leader"]
105 | for level in data1["userCards"]:
106 | if leaderId == level["cardId"]:
107 | card_type = level["defaultImage"]
108 | break
109 | getCd = req.get('https://database.pjsekai.moe/cards.json')
110 | cards_infomation = json.loads(getCd.text)
111 | for sc in cards_infomation:
112 | if leaderId == sc["id"]:
113 | if card_type == 'original':
114 | url = f'https://asset.pjsekai.moe/startapp/thumbnail/chara/{sc["assetbundleName"]}_normal.png'
115 | elif card_type == "special_training":
116 | url = f'https://asset.pjsekai.moe/startapp/thumbnail/chara/{sc["assetbundleName"]}_after_training.png'
117 | l_icon = req.get(url)
118 | return l_icon
119 |
120 |
121 |
122 | async def countFlg(_list,TAG,difficulty,data1):
123 | a_count = 0
124 | for result in data1['userMusicResults']:
125 | if result['musicDifficulty'] == difficulty:
126 | if result[TAG] == True and result['musicId'] not in _list:
127 | a_count = a_count + 1
128 | _list.append(result['musicId'])
129 | return _list,a_count
130 |
131 |
132 | async def countClear(_list,difficulty,data1):
133 | a_count = 0
134 | for result in data1['userMusicResults']:
135 | if result['musicDifficulty'] == difficulty:
136 | if result['fullComboFlg'] == True and result['musicId'] not in _list:
137 | a_count = a_count + 1
138 | _list.append(result['musicId'])
139 | if result['playResult'] == 'clear' and result['musicId'] not in _list:
140 | a_count = a_count + 1
141 | _list.append(result['musicId'])
142 | for a in _list:
143 | if _list.count(a) >= 2:
144 | a_count = account - _list.count(a) + 1
145 | return _list,a_count
146 |
147 | @sv.on_prefix("/pjskpf")
148 | async def pj_profileGet(bot,ev:CQEvent):
149 | #逮捕
150 | uid = ev.user_id
151 | userID = await lg(uid)
152 |
153 | selection = 0
154 |
155 | for i in ev.message:
156 | if i.type == 'at':
157 | uid = int(i.data['qq'])
158 | userID = await lg(uid)
159 | break
160 |
161 | _uID = ev.message.extract_plain_text().strip()
162 | if _uID != "":
163 | _userID = int(_uID)
164 | if isinstance(_userID,int) and _userID > 1000000000000000:
165 | userID = _userID
166 | selection = 1
167 | else:
168 | return await bot.send(ev,f'UID格式错误')
169 |
170 |
171 |
172 | if userID == 0:
173 | await bot.send(ev,f"没有绑定捏\n输入“/pjsk绑定+pjskID”来绑定吧~")
174 | else:
175 | try:
176 | url = f'https://api.pjsekai.moe/api/user/{userID}/profile'
177 | getdata = req.get(url)
178 | data1 = json.loads(getdata.text)
179 |
180 |
181 | dict_backup=[]
182 | difficulty = ['easy','normal','hard','expert','master']
183 | for tag in difficulty:
184 | count = 0
185 | fc_count = 0
186 | ap_count = 0
187 | clr_list = []
188 | fc_list = []
189 | ap_list = []
190 | fc_list,fc_count = await countFlg(fc_list,'fullComboFlg',tag,data1)
191 | ap_list,ap_count = await countFlg(ap_list,'fullPerfectFlg',tag,data1)
192 | clr_list,count = await countClear(clr_list,tag,data1)
193 |
194 | dict_backup.append({tag:{'fc':fc_count,'ap':ap_count,'clear':count}})
195 | #print(dict_backup)
196 |
197 |
198 |
199 | profile_image= Image.open(load_path+'\\test1.png')
200 | new_pimage = load_path+'\\pjprofile.png'
201 |
202 | if selection == 0:
203 | picon = Image.open(BytesIO((await get_usericon(f'{uid}')).content)) #####
204 | else:
205 | picon = Image.open(BytesIO((await getLeaderIcon(data1)).content))
206 |
207 | num_font = ImageFont.truetype(load_path+'\\CAT.TTF',size=40)
208 | name_font = ImageFont.truetype(load_path+'\\zzaw.ttf',size=80)
209 | rank_font = ImageFont.truetype(load_path+'\\CAT.TTF',size=36)
210 | word_font = ImageFont.truetype(load_path+'\\zzaw.ttf',size=32)
211 | draw = ImageDraw.Draw(profile_image)
212 | draw_icon = ImageDraw.Draw(picon)
213 |
214 | #防止部分玩家ID过大导致其以期望外的方式生成
215 | u = data1['user']['userGamedata']['name'].encode("utf-8")
216 | if len(u) < 18:
217 | draw.text((281,130),data1['user']['userGamedata']['name'],'#FFFFFF',font=name_font)
218 | else:
219 | name_font = ImageFont.truetype(load_path+'\\zzaw.ttf',size=48)
220 | draw.text((281,162),data1['user']['userGamedata']['name'],'#FFFFFF',font=name_font)
221 |
222 | draw.text((404,231),str(data1['user']['userGamedata']['rank']),'#FFFFFF',font=rank_font)
223 |
224 |
225 |
226 |
227 | async def measure(msg, font_size, img_width):
228 | i = 0
229 | l = len(msg)
230 | length = 0
231 | positions = []
232 | while i < l :
233 | if re.search(r'[0-9a-zA-Z]', msg[i]):
234 | length += font_size // 2
235 | else:
236 | length += font_size
237 | if length >= img_width:
238 | positions.append(i)
239 | length = 0
240 | i -= 1
241 | i += 1
242 | return positions
243 |
244 | #个人简介
245 |
246 | word_text = Image.new('RGB', (654, 157), "#5b5b5b")
247 |
248 | draw1 = ImageDraw.Draw(word_text)
249 |
250 |
251 | msg = data1['userProfile']['word']
252 | positions = await measure(msg,32,700)
253 | str_list = list(msg)
254 | for pos in positions:
255 | str_list.insert(pos,'\n')
256 | msg = "".join(str_list)
257 |
258 | draw1.text((0,0), msg, "#FFFFFF", font=word_font)
259 | profile_image.paste(word_text, (103,307))
260 |
261 |
262 | def draw_musicsCompleted():
263 | x = 0
264 | for tag in difficulty:
265 | for pdata in dict_backup[x]:
266 | y = 0
267 | for ptag in ['clear','fc','ap']:
268 | draw.text((140 + x * 128,580 + y * 128),str(dict_backup[x][pdata][ptag]),'#FFFFFF',font=num_font)
269 | y = y + 1
270 | x = x + 1
271 |
272 | def characterdataGet():
273 | for i in data1['userCharacters']:
274 | if i["characterId"] % 4 == 0:
275 | x = 960 + (165 * 3)
276 | y = 350 + (107 * (((i["characterId"])// 4)-1))
277 | if i["characterId"] > 20:
278 | y = 130 + (107 * ((((i["characterId"])-20)// 4)-1))
279 | else:
280 | x = 960 + (165 * ((((i["characterId"])) % 4)-1))
281 | y = 350 + (107 * (((i["characterId"])//4)))
282 | if i["characterId"] > 20:
283 | y = 130 + (107 * ((((i["characterId"])-20)// 4)))
284 | draw.text((x, y),str(i['characterRank']),"#000000",font=num_font)
285 |
286 |
287 |
288 | draw_musicsCompleted()
289 | characterdataGet()
290 | picon = picon.resize((177,177),Image.Resampling.LANCZOS)
291 | profile_image.paste(picon, (95,106))
292 | buf = BytesIO()
293 | profile_image.save(buf, format='PNG')
294 | base64_str = f'base64://{base64.b64encode(buf.getvalue()).decode()}' #通过BytesIO发送图片,无需生成本地文件
295 | await bot.send(ev,f'[CQ:image,file={base64_str}]',at_sender = True)
296 | except:
297 | await bot.send(ev,f"api或服务器可能寄了 或者你这个小可爱填错别人ID 不然一般是不会出现意料之外的问题的! \n请及时联系管理员看看发生什么事了")
298 |
299 | def load_event_info(_data):
300 | i = -2
301 | close_time = int(_data[i]["closedAt"]/1000)
302 | if time.time() > close_time: #说明倒数第二个活动已关闭,按最新的算
303 | i = -1
304 | return _data[i]['id'], _data[i]['name'], time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(int(_data[i]["aggregateAt"]/1000))), _data[i]['eventType']
305 |
306 | @sv.on_prefix("/sk")
307 | async def event_rank(bot,ev:CQEvent):
308 | uid = ev.user_id
309 | userid = await lg(uid)
310 | if userid == 0:
311 | await bot.send(ev,f"没有绑定捏\n输入“/pjsk绑定+pjskID”来绑定吧~")
312 | else:
313 | try:
314 | _data = data_req(url_e_data)
315 | event_id, event_name, event_end_time, e_type = load_event_info(_data)
316 | url1 = f'https://api.pjsekai.moe/api/user/%7Buser_id%7D/event/{event_id}/ranking?targetUserId={userid}'
317 |
318 | user_event_data = req.get(url1, headers=headers)
319 | _event_data = json.loads(user_event_data.text)
320 | try:
321 | user_event_rank = _event_data['rankings'][0]['rank'] #你的try嵌套错地方了,如果没打活动这里就取不到值了
322 | user_event_score = _event_data['rankings'][0]['score'] #所以生成消息那边嵌套的try实际没有用
323 | except:
324 | await bot.send(ev, '小可爱你还没打活动查什么呢', at_sender = True)
325 | return #利用return结束
326 | nearest_line = []
327 | event_line = [100, 200, 500,
328 | 1000, 2000, 5000,
329 | 10000, 20000, 50000,
330 | 100000, 200000, 500000,
331 | 1000000, 2000000, 5000000]
332 |
333 | for a in range(len(event_line)):
334 | if int(event_line[a]) >= user_event_rank:
335 | if a != 0:
336 | nearest_line.append(event_line[a-1])
337 | nearest_line.append(event_line[a])
338 | break
339 | else:
340 | nearest_line.append(event_line[-1])
341 |
342 | msg = f"当前活动:{event_name}\n活动类型:{e_type}\n活动截止时间:{event_end_time}\n你的分数:{str(user_event_score)} rank#{str(user_event_rank)}\n最近的分数线:"
343 | for i in nearest_line:
344 | try:
345 | url2 = f'https://api.pjsekai.moe/api/user/%7Buser_id%7D/event/{event_id}/ranking?targetRank={i}'
346 | event_line_data = req.get(url2, headers=headers)
347 | _event_line_data = json.loads(event_line_data.text)
348 | msg += f"\nrank#{i} {str(_event_line_data['rankings'][0]['score'])}"
349 | except:
350 | msg += f"\nrank#{i} 最近的分数线:暂无数据"
351 |
352 | except Exception as e:
353 | msg = f"发生错误,错误类型:{type(e)}\n请联系管理员"
354 | print(e)
355 | await bot.send(ev, msg, at_sender = True)
356 |
357 | def load_req_line(string:str):
358 | return string.replace('k', '000').replace('K', '000').replace('w', '0000').replace('W', '0000')
359 |
360 | @sv.on_prefix('/pjsk档线')
361 | async def event_line_score(bot, ev):
362 | try:
363 | req_line = load_req_line(ev.message.extract_plain_text().strip())
364 | except:
365 | req_line = 0
366 | try:
367 | _data = data_req(url_e_data)
368 | event_id, event_name, event_end_time, e_type = load_event_info(_data)
369 |
370 | #line_score = []
371 | if req_line ==0:
372 | event_line = [100, 200, 500,
373 | 1000, 2000, 5000,
374 | 10000, 20000, 50000,
375 | 100000, 200000, 500000, 1000000]
376 | event_line_msg = ['100', '200', '500',
377 | '1k', '2k', '5k',
378 | '1w', '2w', '5w',
379 | '10w', '20w', '50w', '100w']
380 | index = 0
381 | msg = f'活动标题:{event_name}\n活动类型:{e_type}'
382 | for line in event_line:
383 | url2 = f'https://api.pjsekai.moe/api/user/%7Buser_id%7D/event/{event_id}/ranking?targetRank={line}'
384 | event_line_data = data_req(url2)
385 | try:
386 | #line_score.append(str(event_line_data['rankings'][0]['score'])) #预留后期图像化
387 | line_score = event_line_data['rankings'][0]['score']
388 | msg += f'\n{event_line_msg[index]}线:{line_score}'
389 | except:
390 | #line_score.append('暂无数据')
391 | msg += f'\n{event_line_msg[index]}线:暂无数据'
392 | index += 1
393 | else:
394 | msg = f'活动标题:{event_name}\n活动类型:{e_type}'
395 | url2 = f'https://api.pjsekai.moe/api/user/%7Buser_id%7D/event/{event_id}/ranking?targetRank={req_line}'
396 | event_line_data = data_req(url2)
397 | try:
398 | line_score = event_line_data['rankings'][0]['score']
399 | msg += f'\n{req_line}线:{line_score}'
400 | except:
401 | msg += f'\n{req_line}线:暂无数据'
402 | except Exception as e:
403 | print(e)
404 | msg = f"发生错误,错误类型:{type(e)}\n请联系管理员"
405 |
406 | await bot.send(ev, msg, at_sender = True)
407 |
408 | async def pj_musicCompletedDataGet(uid,data1):
409 | difficulty = 'master'
410 | count = 0
411 | c_count = 0
412 | p_count = 0
413 | list1 = []
414 | list2 = []
415 | list3 = []
416 | list4 = []
417 |
418 | list1,c_count = await countFlg(list1,'fullComboFlg',difficulty,data1)
419 | list2,p_count = await countFlg(list2,'fullPerfectFlg',difficulty,data1)
420 | list4,count = await countClear(list4,difficulty,data1)
421 |
422 | _lv = data_req(url_getmD)
423 | allMusic = data_req(url_getmc)
424 | #按难度分类
425 | for _ in allMusic:
426 | list3.append(_['id'])
427 |
428 | async def selectPlus(_list):
429 | lv_s = {26:0,27:0,28:0,29:0,30:0,31:0,32:0,33:0,34:0,35:0,36:0}
430 | for __lv in _lv:
431 | if __lv['musicDifficulty'] == difficulty and __lv['musicId'] in _list:
432 | lv_s[__lv['playLevel']] += 1
433 | return lv_s
434 |
435 | lv1 = await selectPlus(list1)
436 | lv2 = await selectPlus(list2)
437 | lv3 = await selectPlus(list3)
438 | lv4 = await selectPlus(list4)
439 |
440 |
441 | async def change(lv):
442 | re_lv1 = []
443 | in_dex ={}
444 | for i in range(26,37):
445 | a = lv[i]
446 | b = str(i)
447 | in_dex[f"{b}"] = a
448 | n_dex =in_dex
449 | re_lv1.append(n_dex)
450 | return re_lv1
451 |
452 | re_lv1 = await change(lv1) #fc
453 | re_lv2 = await change(lv2) #ap
454 | _all = await change(lv3) #all
455 | _clear = await change(lv4) #clear
456 |
457 |
458 | return _clear,_all,re_lv1,re_lv2
459 |
460 |
461 | async def get_usericon(user):
462 | p_icon = req.get(f'https://q1.qlogo.cn/g?b=qq&nk={user}&s=640')
463 | return p_icon
464 |
465 | @sv.on_prefix("/pjsk进度")
466 | async def gen_pjsk_jindu_image(bot,ev:CQEvent):
467 | #逮捕
468 | uid = ev.user_id
469 | userID = await lg(uid)
470 |
471 | selection = 0
472 |
473 | for i in ev.message:
474 | if i.type == 'at':
475 | uid = int(i.data['qq'])
476 | userID = await lg(uid)
477 | break
478 |
479 | _uID = ev.message.extract_plain_text().strip()
480 | if _uID != "":
481 | _userID = int(_uID)
482 | if isinstance(_userID,int) and _userID > 1000000000000000:
483 | userID = _userID
484 | selection = 1
485 | else:
486 | return await bot.send(ev,f'UID格式错误')
487 |
488 |
489 |
490 | if userID == 0:
491 | await bot.send(ev,f"没有绑定捏\n输入“/pjsk绑定+pjskID”来绑定吧~")
492 |
493 | else:
494 | try:
495 | url = f'https://api.pjsekai.moe/api/user/{str(userID)}/profile'
496 | getdata = req.get(url)
497 | data1 = json.loads(getdata.text)
498 |
499 | _clr,_all,_fc,_ap = await pj_musicCompletedDataGet(uid,data1)
500 | image1 = Image.open(load_path+f'\\test.png')
501 | new_image =load_path+f'\\pjskjindu.png'
502 |
503 |
504 | if selection == 0:
505 | icon = Image.open(BytesIO((await get_usericon(f'{uid}')).content)) #####
506 | else:
507 | icon = Image.open(BytesIO((await getLeaderIcon(data1)).content))
508 |
509 | font = ImageFont.truetype(load_path+f'\\CAT.TTF',size=40)
510 | font1 = ImageFont.truetype(load_path+f'\\zzaw.ttf',size=50)
511 | font2 = ImageFont.truetype(load_path+f'\\CAT.TTF',size=36)
512 | draw = ImageDraw.Draw(image1)
513 |
514 | u = data1['user']['userGamedata']['name'].encode("utf-8")
515 | if len(u) < 18:
516 | draw.text((214,75),data1['user']['userGamedata']['name'],'#000000',font=font1)
517 | else:
518 | font1 = ImageFont.truetype(load_path+f'\\zzaw.ttf',size=30)
519 | draw.text((214,95),data1['user']['userGamedata']['name'],'#000000',font=font1)
520 |
521 | draw.text((315,135),str(data1['user']['userGamedata']['rank']), "#FFFFFF",font=font2)
522 | icon = icon.resize((117,117),Image.Resampling.LANCZOS)
523 | image1.paste(icon, (67,57))
524 |
525 | for i in _ap[0]:
526 | if i <= '31':
527 | draw.text((167,284+(97*(int(i)-26))),str(_ap[0][i]), color["ap"],font=font)
528 | else:
529 | draw.text((667,284+(97*(int(i)-32))),str(_ap[0][i]), color["ap"],font=font)
530 | for i in _fc[0]:
531 | if i <= '31':
532 | draw.text((242,284+(97*(int(i)-26))),str(_fc[0][i]), color["fc"],font=font)
533 | else:
534 | draw.text((742,284+(97*(int(i)-32))),str(_fc[0][i]), color["fc"],font=font)
535 |
536 | for i in _clr[0]:
537 | if i <= '31':
538 | draw.text((317,284+(97*(int(i)-26))),str(_clr[0][i]), color["clr"],font=font)
539 | else:
540 | draw.text((817,284+(97*(int(i)-32))),str(_clr[0][i]), color["clr"],font=font)
541 | for i in _all[0]:
542 | if i <= '31':
543 | draw.text((392,284+(97*(int(i)-26))),str(_all[0][i]), color["all"],font=font)
544 | else:
545 | draw.text((892,284+(97*(int(i)-32))),str(_all[0][i]), color["all"],font=font)
546 |
547 | buf = BytesIO()
548 | image1.save(buf, format='PNG')
549 | base64_str = f'base64://{base64.b64encode(buf.getvalue()).decode()}'
550 | await bot.send(ev,f'[CQ:image,file={base64_str}]',at_sender = True)
551 | except:
552 | await bot.send(ev,f"api或服务器可能寄了 或者你这个小可爱填错别人ID 不然一般是不会出现意料之外的问题的! \n请及时联系管理员看看发生什么事了")
553 |
554 |
555 | '''
556 | userID = await lg(uid)
557 | url = f'https://api.pjsekai.moe/api/user/{userID}/profile'
558 | getdata = req.get(url)
559 | data1 = json.loads(getdata.text)
560 | #print(data1)
561 | '''
562 | ''' 备份 给新功能测试
563 | loop = asyncio.get_event_loop()
564 | loop.run_until_complete(pj_profileGet())
565 | loop.close()
566 | '''
567 |
--------------------------------------------------------------------------------
/test.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FLAG250/hoshino-plugin-pjsk/13ecea83d2bdb3ef1bf5fbecc2f0e4a08a88d822/test.png
--------------------------------------------------------------------------------
/test1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FLAG250/hoshino-plugin-pjsk/13ecea83d2bdb3ef1bf5fbecc2f0e4a08a88d822/test1.png
--------------------------------------------------------------------------------
/text.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FLAG250/hoshino-plugin-pjsk/13ecea83d2bdb3ef1bf5fbecc2f0e4a08a88d822/text.png
--------------------------------------------------------------------------------
/zzaw.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FLAG250/hoshino-plugin-pjsk/13ecea83d2bdb3ef1bf5fbecc2f0e4a08a88d822/zzaw.ttf
--------------------------------------------------------------------------------