Skip to content

Commit

Permalink
Merge branch 'develop'
Browse files Browse the repository at this point in the history
  • Loading branch information
musnows committed Jan 24, 2023
2 parents 311f3c7 + 1357073 commit b7582d6
Show file tree
Hide file tree
Showing 9 changed files with 297 additions and 374 deletions.
45 changes: 32 additions & 13 deletions code/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import traceback
from aiohttp import web
from endpoints.Gtime import GetTime
from endpoints.ApiHandler import base_img_request,tfa_code_requeset,afd_request
from endpoints.ApiHandler import tfa_code_requeset,afd_request,login_img_request,img_draw_request

# 初始化节点
routes = web.RouteTableDef()
Expand All @@ -12,46 +12,61 @@
@routes.get('/')
def hello_world(request): # put application's code here
print(f"[{GetTime()}] [request] /")
return web.Response(body=json.dumps({'code':0,'message': 'Hello! Use path /shop-url or /shop-img to get valorant daily shop','info':'在path后添加/shop-img或者/shop-url来获取每日商店,前者会直接跳转,后者返回一个带图片url的json。示例: /shop-url?account=Riot账户&passwd=Riot密码&img_src=可选参数,自定义背景图'},ensure_ascii=False), status=200, content_type='application/json')
return web.Response(body=json.dumps({
'code':0,
'message': 'Hello! Use path /shop-url or /shop-img to get valorant daily shop','info':'在path后添加/shop-img或者/shop-url来获取每日商店,前者会直接跳转,后者返回一个带图片url的json。示例: /shop-url?account=Riot账户&passwd=Riot密码&img_src=可选参数,自定义背景图','docs':'https://github.com/Aewait/Kook-Valorant-Bot/blob/main/docs/valorant-shop-img-api.md'
},indent=2, sort_keys=True,ensure_ascii=False), status=200, content_type='application/json')

# 提供4个皮肤uuid,返回图片
@routes.get('/shop-draw')
async def get_dailshop_img(request):
print(f"[{GetTime()}] [request] /shop-draw")
try:
ret = await img_draw_request(request)
return web.Response(body=json.dumps(ret,indent=2, sort_keys=True,ensure_ascii=False), content_type='application/json')
except:
err_cur = traceback.format_exc()
print(f"[{GetTime()}] [Api] ERR in /shop-url\n{err_cur}")
return web.Response(body=json.dumps({'code':200,'message': 'unkown err','info':f'未知错误','except':f'{err_cur}'},indent=2, sort_keys=True,ensure_ascii=False), content_type='application/json')


# 直接跳转图片
@routes.get('/shop-img')
async def get_dailshop_img(request):
print(f"[{GetTime()}] [request] /shop-img")
try:
ret = await base_img_request(request)
ret = await login_img_request(request)
if ret['code']==0:
return web.Response(headers={'Location': ret['message']},status=303) # 303是直接跳转到图片
else:
return web.Response(body=json.dumps(ret,ensure_ascii=False), content_type='application/json')
return web.Response(body=json.dumps(ret,indent=2, sort_keys=True,ensure_ascii=False), content_type='application/json')
except:
err_cur = traceback.format_exc()
print(f"[{GetTime()}] [Api] ERR in /shop-img\n{err_cur}")
return web.Response(body=json.dumps({'code':200,'message': 'unkown err','info':f'未知错误','except':f'{err_cur}'},ensure_ascii=False), content_type='application/json')
return web.Response(body=json.dumps({'code':200,'message': 'unkown err','info':f'未知错误','except':f'{err_cur}'},indent=2, sort_keys=True,ensure_ascii=False), content_type='application/json')

# 获取图片url
@routes.get('/shop-url')
async def get_dailshop_img(request):
print(f"[{GetTime()}] [request] /shop-url")
try:
ret = await base_img_request(request)
return web.Response(body=json.dumps(ret,ensure_ascii=False), content_type='application/json')
ret = await login_img_request(request)
return web.Response(body=json.dumps(ret,indent=2, sort_keys=True,ensure_ascii=False), content_type='application/json')
except:
err_cur = traceback.format_exc()
print(f"[{GetTime()}] [Api] ERR in /shop-url\n{err_cur}")
return web.Response(body=json.dumps({'code':200,'message': 'unkown err','info':f'未知错误','except':f'{err_cur}'},ensure_ascii=False), content_type='application/json')
return web.Response(body=json.dumps({'code':200,'message': 'unkown err','info':f'未知错误','except':f'{err_cur}'},indent=2, sort_keys=True,ensure_ascii=False), content_type='application/json')

@routes.post('/tfa')
async def post_tfa_code(request):
print(f"[{GetTime()}] [request] /tfa")
try:
ret = await tfa_code_requeset(request)
return web.Response(body=json.dumps(ret,ensure_ascii=False), content_type='application/json')
return web.Response(body=json.dumps(ret,indent=2, sort_keys=True,ensure_ascii=False), content_type='application/json')
except:
err_cur = traceback.format_exc()
print(f"[{GetTime()}] [Api] ERR in /tfa\n{err_cur}")
return web.Response(body=json.dumps({'code':200,'message': 'unkown err','info':f'未知错误','except':f'{err_cur}'},ensure_ascii=False), content_type='application/json')
return web.Response(body=json.dumps({'code':200,'message': 'unkown err','info':f'未知错误','except':f'{err_cur}'},indent=2, sort_keys=True,ensure_ascii=False), content_type='application/json')

from main import bot
# 爱发电的wh
Expand All @@ -60,14 +75,18 @@ async def aifadian_webhook(request):
print(f"[{GetTime()}] [request] /afd")
try:
ret = await afd_request(request,bot)
return web.Response(body=json.dumps(ret,ensure_ascii=False), content_type='application/json')
return web.Response(body=json.dumps(ret,indent=2, sort_keys=True,ensure_ascii=False), content_type='application/json')
except:
err_cur = traceback.format_exc()
print(f"[{GetTime()}] [Api] ERR in /afd\n{err_cur}")
return web.Response(body=json.dumps({"ec":0,"em":"err ouccer"},ensure_ascii=False), content_type='application/json')
return web.Response(body=json.dumps({"ec":0,"em":"err ouccer"},indent=2, sort_keys=True,ensure_ascii=False), content_type='application/json')


print(f"[API Start] starting at {GetTime()}")
app = web.Application()
app.add_routes(routes)
#web.run_app(app, host='127.0.0.1', port=14726)
if __name__ == '__main__':
try:
web.run_app(app, host='127.0.0.1', port=14726)
except:
print(traceback.format_exc())
103 changes: 64 additions & 39 deletions code/endpoints/ApiHandler.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,12 +47,66 @@ async def check_token_rate(token:str):



# 基本操作
async def base_img_request(request):
# 基本画图操作
async def base_img_request(params,list_shop,vp1='0',rp1='0'):
# 自定义背景
if 'img_src' in params:
img_src = params['img_src']
else:
img_src = img_bak_169 # 默认背景16-9
if 'img_ratio'in params and params['img_ratio']=='1':
img_src = img_bak_11 # 默认背景1-1

# 开始画图
start = time.perf_counter()
if 'img_ratio' in params and params['img_ratio']=='1':
ret = await get_shop_img_11(list_shop,bg_img_src=img_src)
else:# 只有16-9的图片需获取vp和r点
ret = await get_shop_img_169(list_shop,vp=vp1,rp=rp1,bg_img_src=img_src)
# 打印计时
print(f"[{GetTime()}] [IMGdraw]",format(time.perf_counter() - start, '.2f'))# 结果为浮点数,保留两位小数

start = time.perf_counter()
if ret['status']:
bg = ret['value']
img_src_ret = await kook_create_asset(api_bot_token,bg) # 上传图片
if img_src_ret['code']==0:
print(f"[{GetTime()}] [Api] kook_create_asset success {format(time.perf_counter() - start, '.2f')}")
dailyshop_img_src = img_src_ret['data']['url']
print(f'[{GetTime()}] [img-url] {dailyshop_img_src}')
return {'code':0,'message':dailyshop_img_src,'info':'商店图片获取成功'}
else:
print(f'[{GetTime()}] [Api] kook_create_asset failed')
return {'code':200,'message': 'img upload err','info':'图片上传错误'}
else: #出现图片违规或者url无法获取
err_str = ret['value']
print(f'[{GetTime()}] [ERR]',err_str)
return {'code':200,'message': 'img src err','info':'自定义图片获取失败'}

# 画图接口(仅画图)
async def img_draw_request(request):
params = request.rel_url.query
if "list_shop" not in params or 'token' not in params:
print(f"ERR! [{GetTime()}] params needed: token/list_shop")
return {'code': 400, 'message': 'params needed: token/list_shop','info':'缺少参数!示例: /shop-draw?token=api凭证&list_shop=四个皮肤uuid的list&vp=vp(可选)&rp=rp(可选)&img_src=自定义背景图(可选)','docs':'https://github.com/Aewait/Kook-Valorant-Bot/blob/main/docs/valorant-shop-img-api.md'}

list_shop = params['list_shop']
token = params['token']
ck_ret = await check_token_rate(token)
if not ck_ret['status']:
return {'code': 200, 'message': ck_ret['message'],'info':ck_ret['info']}
# vp和rp必须同时给予,只给一个不算
if 'vp' not in params or 'rp' not in params:
return await base_img_request(params,list_shop)
else:
return await base_img_request(params,list_shop,params['vp'],params['rp'])

# 登录+画图
async def login_img_request(request):
params = request.rel_url.query
if 'account' not in params or 'passwd' not in params or 'token' not in params:
print(f"ERR! [{GetTime()}] params needed: token/account/passwd")
return {'code': 400, 'message': 'params needed: token/account/passwd','info':'缺少参数!示例: /shop-img?token=api凭证&account=Riot账户&passwd=Riot密码&img_src=自定义背景图(可选)'}
return {'code': 400, 'message': 'params needed: token/account/passwd','info':'缺少参数!示例: /shop-img?token=api凭证&account=Riot账户&passwd=Riot密码&img_src=自定义背景图(可选)','docs':'https://github.com/Aewait/Kook-Valorant-Bot/blob/main/docs/valorant-shop-img-api.md'}

account=params['account']
passwd=params['passwd']
Expand Down Expand Up @@ -86,48 +140,19 @@ async def base_img_request(request):
resp = await fetch_daily_shop(userdict) #获取每日商店
print(f'[{GetTime()}] [Api] fetch_daily_shop success')
list_shop = resp["SkinsPanelLayout"]["SingleItemOffers"] # 商店刷出来的4把枪

# 自定义背景
if 'img_src' in params:
img_src = params['img_src']
else:
img_src = img_bak_169 # 默认背景16-9
if 'img_ratio'in params and params['img_ratio']=='1':
img_src = img_bak_11 # 默认背景1-1

# 开始画图
start = time.perf_counter()
if 'img_ratio' in params and params['img_ratio']=='1':
ret = await get_shop_img_11(list_shop,bg_img_src=img_src)
else:
res_vprp={'vp':'0','rp':'0'} # 先初始化为0
if 'img_ratio' not in params or params['img_ratio']!='1':
res_vprp = await fetch_vp_rp_dict(userdict) # 只有16-9的图片需获取vp和r点
ret = await get_shop_img_169(list_shop,vp=res_vprp['vp'],rp=res_vprp['rp'],bg_img_src=img_src)
# 打印计时
print(f"[{GetTime()}] [IMGdraw]",format(time.perf_counter() - start, '.2f'))# 结果为浮点数,保留两位小数
# 不管什么情况,都请求这个
return await base_img_request(params,list_shop,res_vprp['vp'],res_vprp['rp'])

start = time.perf_counter()
if ret['status']:
bg = ret['value']
img_src_ret = await kook_create_asset(api_bot_token,bg) # 上传图片
if img_src_ret['code']==0:
print(f"[{GetTime()}] [Api] kook_create_asset success {format(time.perf_counter() - start, '.2f')}")
dailyshop_img_src = img_src_ret['data']['url']
print(f'[{GetTime()}] [img-url] {dailyshop_img_src}')
return {'code':0,'message':dailyshop_img_src,'info':'商店图片获取成功'}
else:
print(f'[{GetTime()}] [Api] kook_create_asset failed')
return {'code':200,'message': 'img upload err','info':'图片上传错误'}
else: #出现图片违规或者url无法获取
err_str = ret['value']
print(f'[{GetTime()}] [ERR]',err_str)
return {'code':200,'message': 'img src err','info':'自定义图片获取失败'}

# 邮箱验证的post
async def tfa_code_requeset(request):
params = request.rel_url.query
if 'account' not in params or 'vcode' not in params or 'token' not in params:
print(f"ERR! [{GetTime()}] params needed: token/account/vcode")
return {'code': 400, 'message': 'params needed: token/account/vcode','info':'缺少参数!示例: /tfa?token=api凭证&account=Riot账户&vcode=邮箱验证码'}
return {'code': 400, 'message': 'params needed: token/account/vcode','info':'缺少参数!示例: /tfa?token=api凭证&account=Riot账户&vcode=邮箱验证码','docs':'https://github.com/Aewait/Kook-Valorant-Bot/blob/main/docs/valorant-shop-img-api.md'}

account=params['account']
vcode=params['vcode']
Expand Down Expand Up @@ -155,8 +180,8 @@ async def afd_request(request,bot):
if 'plan_title' in params['data']['order']:
text =f"商品 {params['data']['order']['plan_title']}\n"
user_id = params['data']['order']['user_id']
user_id = user_id[:6]
text+=f"用户 {params['data']['order']['user_id']}\n"
user_id = user_id[0:6]
text+=f"用户 {user_id}\n"
for i in params['data']['order']['sku_detail']:
text+=f"发电了{i['count']}{i['name']}\n"
text+=f"共计 {params['data']['order']['total_amount']} 猿"
Expand Down
27 changes: 14 additions & 13 deletions code/endpoints/BotLog.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import traceback
from khl import Message, PrivateMessage, Bot
from khl.card import Card, CardMessage, Element, Module, Types, Struct
from endpoints.KookApi import guild_list, guild_view, upd_card, icon_cm
from endpoints.KookApi import guild_list, guild_view, upd_card, get_card, icon_cm
from PIL import Image, ImageDraw, ImageFont
from copy import deepcopy

Expand Down Expand Up @@ -114,8 +114,8 @@ async def log_bot_list(msg:Message):
async def APIRequestFailed_Handler(def_name:str,excp,msg:Message,bot:Bot,send_msg=None,cm:CardMessage=None):
err_str = f"ERR! [{GetTime()}] {def_name} APIRequestFailed\n{excp}"
print(err_str)
cm0 = CardMessage()
c = Card(color='#fb4b57')
text = f"啊哦,出现了一些问题"
text_sub= 'e'
if "引用不存在" in excp:#引用不存在的时候,直接向频道或者用户私聊重新发送消息
if isinstance(msg, PrivateMessage):
cur_user = await bot.client.fetch_user(msg.author_id)
Expand All @@ -124,17 +124,18 @@ async def APIRequestFailed_Handler(def_name:str,excp,msg:Message,bot:Bot,send_ms
cur_ch = await bot.client.fetch_public_channel(msg.ctx.channel.id)
await bot.send(cur_ch,cm)
print(f"[APIRequestFailed.Handler] Au:{msg.author_id} 引用不存在, cm_send success!")
return
elif "json没有通过验证" in excp:
print(f"ERR! Au:{msg.author_id} json.dumps(cm)")
print(json.dumps(cm))
text = f"啊哦,发送的消息出现了一些问题"
c.append(Module.Section(Element.Text(text, Types.Text.KMD), Element.Image(src=icon_cm.lagging, size='sm')))
c.append(Module.Context(Element.Text(f"卡片消息json没有通过验证或者不存在", Types.Text.KMD)))
cm0.append(c)
if send_msg != None: # 非none则执行更新消息,而不是直接发送
await upd_card(send_msg['msg_id'], cm0, channel_type=msg.channel_type)
else:
await msg.reply(cm0)
print(f"ERR! Au:{msg.author_id} json.dumps(cm) = {json.dumps(cm)}")
text_sub = f"卡片消息json没有通过验证或者不存在"
elif "屏蔽" in excp:
text_sub = f"阿狸无法向您发出私信,请检查你的隐私设置"

cm0 = await get_card(text,text_sub,icon_cm.lagging)
if send_msg != None: # 非none则执行更新消息,而不是直接发送
await upd_card(send_msg['msg_id'], cm0, channel_type=msg.channel_type)
else:
await msg.reply(cm0)

# 基础错误的处理,带login提示(部分命令不需要这个提示)
async def BaseException_Handler(def_name:str,excp,msg:Message,bot:Bot,send_msg=None,cm:CardMessage=None,help="您可能需要重新执行/login操作"):
Expand Down
2 changes: 1 addition & 1 deletion code/endpoints/Help.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,8 @@ def help_val():
c3.append(Module.Section(Element.Text(text, Types.Text.KMD)))
c3.append(Module.Divider())
help_1 = "「/bundle 皮肤名」 查询皮肤系列包含什么枪械\n"
help_1 += "「/lead」 显示出当前游戏的排行榜。可提供参数1前多少位,参数2过滤胜场。如`/lead 20 30`代表排行榜前20位胜场超过30的玩家\n"
help_1 += "「/login 账户 密码」请`私聊`使用,登录您的riot账户\n"
help_1 += "「/login 账户 密码 1」邮箱验证登录,请`私聊`使用\n"
help_1 += "「/shop」 查询您的每日商店\n"
help_1 += "「/night」查询您的夜市(未完工)\n"
help_1 += "「/uinfo」查询当前装备的卡面/称号/剩余vp和r点\n"
Expand Down
26 changes: 24 additions & 2 deletions code/endpoints/KookApi.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import aiohttp
import io
from khl import Bot,ChannelPrivacyTypes
from khl.card import Card,CardMessage,Module,Element,Types

from endpoints.FileManage import config
# 下方更新卡片消息需要bot
Expand Down Expand Up @@ -76,14 +77,22 @@ async def kook_create_asset(bot_token:str,bg):
imgByte = imgByteArr.getvalue()
data = aiohttp.FormData()
data.add_field('file',imgByte)
url = "https://www.kookapp.cn/api/v3/asset/create"
url = kook_base_url+"/api/v3/asset/create"
kook_headers = {f'Authorization': f"Bot {bot_token}"}
body = {'file':data}
async with aiohttp.ClientSession() as session:
async with session.post(url, headers=kook_headers,data=data) as response:
res = json.loads(await response.text())
return res

# 下线机器人
async def bot_offline():
url = kook_base_url+"/api/v3/user/offline"
async with aiohttp.ClientSession() as session:
async with session.post(url, headers=kook_headers) as response:
res = json.loads(await response.text())
return res

##########################################icon##############################################

from typing import Union
Expand Down Expand Up @@ -134,4 +143,17 @@ async def upd_card(msg_id: str,
result = await bot.client.gate.request('POST', 'message/update', data=data)
else:
result = await bot.client.gate.request('POST', 'direct-message/update', data=data)
return result
return result

# 获取常用的卡片消息
async def get_card(text:str,sub_text='e',img_url='e',card_color='#fb4b57',img_sz='sm'):
cm = CardMessage()
c = Card(color=card_color)
if img_url != 'e':
c.append(Module.Section(Element.Text(text, Types.Text.KMD), Element.Image(src=img_url, size=img_sz)))
else:
c.append(Module.Section(Element.Text(text, Types.Text.KMD)))
if sub_text != 'e':
c.append(Module.Context(Element.Text(sub_text, Types.Text.KMD)))
cm.append(c)
return cm
3 changes: 2 additions & 1 deletion code/endpoints/ValFileUpd.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,8 @@ async def update_price(msg: Message,userdict):
global ValPriceList
# 调用api获取价格列表
prices = await fetch_item_price_all(userdict)
if "Offers" not in prices:#键值不在,获取错误
if "errorCode" in prices:#键值不在,获取错误
print(f"ERR! [{GetTime()}] update_item_price:\n{prices}")
raise Exception("KeyError, fetch price failed!")
ValPriceList.value = prices # 所有价格的列表
# 写入文件
Expand Down
Loading

0 comments on commit b7582d6

Please sign in to comment.