diff --git a/src/plugins/github/__init__.py b/src/plugins/github/__init__.py
index 3e476a9c..fb7a4a03 100644
--- a/src/plugins/github/__init__.py
+++ b/src/plugins/github/__init__.py
@@ -116,7 +116,7 @@ async def recWebHook(req: Request):
except Exception as e:
msg = f"Event {event} has not been supported."
return {"status": "500", "message": msg, "error": e}
- bots: list = list(Config.bot_basic.bot_notice.__dict__)
+ bots: list = list(Config.bot_basic.bot_notice)
for i in bots:
bot = get_bot(i)
await sendm(bot, message, repo)
diff --git a/src/plugins/jx3/attributes/api.py b/src/plugins/jx3/attributes/api.py
index 3f802334..81313fcd 100644
--- a/src/plugins/jx3/attributes/api.py
+++ b/src/plugins/jx3/attributes/api.py
@@ -220,7 +220,7 @@ def kungfu_mapping(kf) -> Union[str, bool]:
return False
-async def get_attr_main(server, id, group_id):
+async def get_attr_main(server, id, group_id, exist_data: dict = {}):
server = server_mapping(server, group_id)
if not server:
return [PROMPT.ServerNotExist]
@@ -253,8 +253,11 @@ async def get_attr_main(server, id, group_id):
"User-Agent": "SeasunGame/193 CFNetwork/1240.0.4 Darwin/20.6.0",
"x-sk": xsk
}
- data = await post_url(url="https://m.pvp.xoyo.com/mine/equip/get-role-equip", data=param, headers=headers)
- data = json.loads(data)
+ if exist_data:
+ data = exist_data
+ else:
+ data = await post_url(url="https://m.pvp.xoyo.com/mine/equip/get-role-equip", data=param, headers=headers)
+ data = json.loads(data)
kfid = data["data"]["Kungfu"]["KungfuID"]
kf = await get_personal_kf(kfid)
if not kf:
diff --git a/src/plugins/jx3/calculator/__init__.py b/src/plugins/jx3/calculator/__init__.py
new file mode 100644
index 00000000..e9f27988
--- /dev/null
+++ b/src/plugins/jx3/calculator/__init__.py
@@ -0,0 +1,39 @@
+from nonebot import on_command
+from nonebot.adapters import Message
+from nonebot.adapters.onebot.v11 import GroupMessageEvent, MessageSegment as ms
+from nonebot.params import CommandArg
+
+from src.tools.permission import checker, error
+from src.tools.utils.file import get_content_local
+
+from src.plugins.sign import Sign
+
+from .universe import (
+ dj_calculator
+)
+
+calc = on_command("jx3_calculator_dj", aliases={"毒经计算器"}, priority=5) # 目前先对毒经的计算器进行响应,后续尽可能多地支持
+
+@calc.handle()
+async def _(event: GroupMessageEvent, args: Message = CommandArg()):
+ if args.extract_plain_text() == "":
+ return
+ if not checker(str(event.user_id), 10) and Sign.get_coin(str(event.user_id)) < 500:
+ await calc.finish(error(10))
+ if not checker(str(event.user_id), 10):
+ Sign.reduce(str(event.user_id), 500)
+ arg = args.extract_plain_text().split(" ")
+ if len(arg) not in [1, 2]:
+ await calc.finish("唔……参数不正确哦,请检查后重试~")
+ if len(arg) == 1:
+ server = None
+ id = arg[0]
+ elif len(arg) == 2:
+ server = arg[0]
+ id = arg[1]
+ data = await dj_calculator(server, id, str(event.group_id))
+ if isinstance(data, list):
+ await calc.finish(data[0])
+ elif isinstance(data, str):
+ data = get_content_local(data)
+ await calc.finish(ms.image(data))
\ No newline at end of file
diff --git a/src/plugins/jx3/calculator/dj.py b/src/plugins/jx3/calculator/dj.py
new file mode 100644
index 00000000..aa1269af
--- /dev/null
+++ b/src/plugins/jx3/calculator/dj.py
@@ -0,0 +1,186 @@
+from typing import List, Union, Literal, Optional
+from jinja2 import Template
+from pathlib import Path
+from pydantic import BaseModel
+
+from src.tools.utils.request import post_url
+from src.tools.basic.server import server_mapping, Zone_mapping
+from src.tools.basic.prompts import PROMPT
+from src.tools.basic.jx3 import gen_ts
+from src.tools.utils.file import read, write
+from src.tools.utils.path import ASSETS, CACHE, VIEWS
+from src.tools.generate import get_uuid, generate
+from src.tools.config import Config
+
+from src.plugins.jx3.bind.role import get_player_local_data
+from src.plugins.jx3.detail.detail import get_tuilan_data
+from src.plugins.jx3.attributes.api import get_personal_kf
+
+import json
+
+template_calculator_dujing = """
+
+ {{ skill }} |
+
+
+ |
+ {{ count }} |
+ {{ value }} |
+
"""
+
+class ExcelRequest(BaseModel):
+ attrs: List[Union[int, str]]
+ weapon: Literal["", "墨语沉香", "13950水特效", "龙门飞剑", "小橙武特效"]
+ sash: Literal["", "秋风韵"]
+ enchant: List[bool]
+ suit: List[bool]
+
+inkarsuki_offical_token = Config.hidden.offcial_token
+
+async def get_calculated_data(
+ attrs: List[Union[int, str]],
+ weapon: Literal["", "墨语沉香", "13950水特效", "龙门飞剑", "小橙武特效"],
+ sash: Literal["", "秋风韵"],
+ enchant: List[bool],
+ suit: List[bool]
+) -> dict:
+ params = {
+ "attrs": attrs,
+ "weapon": weapon,
+ "sash": sash,
+ "enchant": enchant,
+ "suit": suit
+ }
+ data = await post_url(
+ url = "http://117.50.178.116:2333/calculator",
+ json = params,
+ headers = {
+ "token": inkarsuki_offical_token
+ }
+ )
+ return json.loads(data)
+
+def check_set_effects(equip_list):
+ skill_event_handler_activated = False
+ set_equipment_recipe_activated = False
+
+ for equip in equip_list:
+ if "SetListMap" in equip and "Set" in equip:
+ equipped_set_pieces = len(equip["SetListMap"])
+
+ for effect in equip["Set"]:
+ set_num = int(effect.get("SetNum", 0))
+
+ if effect["Desc"] == "atSkillEventHandler" and equipped_set_pieces >= set_num:
+ skill_event_handler_activated = True
+
+ if effect["Desc"] == "atSetEquipmentRecipe" and equipped_set_pieces >= set_num:
+ set_equipment_recipe_activated = True
+
+ return [skill_event_handler_activated, set_equipment_recipe_activated]
+
+async def analyze_attrs(attrs_raw_data: dict) -> ExcelRequest:
+ weapon = ""
+ sash = ""
+ enchant = []
+ suit = []
+ for equip in attrs_raw_data["data"]["Equips"]:
+ if equip["Icon"]["Kind"] == "武器" and equip["Icon"]["SubKind"] != "投掷囊":
+ if equip["Name"] == "十方断魂笛·虫魂" and equip["Quality"] == "13200":
+ weapon = "龙门飞剑"
+ if equip["Name"] == "墨语沉香" and equip["Quality"] == "12500":
+ weapon = "墨语沉香"
+ if equip["Name"] == "悠哉乐土":
+ weapon = "13950水特效"
+ if equip["Name"] == "死生往复·牵丝" and equip["Quality"] == "11650":
+ weapon = "小橙武特效"
+ if equip["Icon"]["SubKind"] == "腰坠":
+ if equip["Name"] == "秋风韵":
+ sash = "秋风韵"
+ for place in ["帽子", "上衣", "腰带", "护臂", "鞋"]:
+ flag = False
+ for equip in attrs_raw_data["data"]["Equips"]:
+ if equip["Icon"]["SubKind"] == place:
+ if "WPermanentEnchant" in equip:
+ enchant.append(True)
+ flag = True
+ else:
+ enchant.append(False)
+ flag = True
+ if not flag:
+ enchant.append(False)
+ suit = check_set_effects(attrs_raw_data["data"]["Equips"])
+ panel = attrs_raw_data["data"]["PersonalPanel"]
+ attrs = []
+ for attr_name in ["根骨", "基础攻击力", "会心", "会心效果", "破防", "破招", "无双", "加速"]:
+ for attr_data in panel:
+ if attr_data["name"] == attr_name:
+ if attr_data["percent"] and attr_name != "加速":
+ attrs.append(str(attr_data["value"]) + "%")
+ if not attr_data["percent"] and attr_name != "加速":
+ attrs.append(attr_data["value"])
+ if attr_name == "加速":
+ attrs.append("%.2f%%" % (attr_data["value"]/96483.75 * 100))
+ return ExcelRequest(
+ attrs=attrs,
+ weapon=weapon,
+ sash=sash,
+ enchant=enchant,
+ suit=suit
+ )
+
+async def generate_calculator_img_dujing(server: Optional[str], name: str, group_id: str = ""):
+ server = server_mapping(server, group_id)
+ if not server:
+ return [PROMPT.ServerNotExist]
+ role_data = await get_player_local_data(role_name=name, server_name=server)
+ if role_data.format_jx3api()["code"] != 200:
+ return [PROMPT.PlayerNotExist]
+ uid = role_data.format_jx3api()["data"]["roleId"]
+ param = {
+ "zone": Zone_mapping(server),
+ "server": server,
+ "game_role_id": uid,
+ "ts": gen_ts()
+ }
+ equip_data = await get_tuilan_data("https://m.pvp.xoyo.com/mine/equip/get-role-equip", param)
+ kungfu = await get_personal_kf(equip_data["data"]["Kungfu"]["KungfuID"])
+ if kungfu != "毒经":
+ return ["唔……门派与计算器不匹配!"]
+ analyzed_data: ExcelRequest = await analyze_attrs(equip_data)
+ calculated_data = await get_calculated_data(**(analyzed_data.__dict__))
+ tables = []
+ max_dps = calculated_data["data"]["result"] # 理论DPS
+ avg_dps = max_dps*0.95 # 一般手法
+ min_dps = max_dps*0.825 # 一键宏
+ for skill_sort in range(len(calculated_data["data"]["skills"])):
+ tables.append(
+ Template(template_calculator_dujing).render(**{
+ "skill": calculated_data["data"]["skills"][skill_sort],
+ "display": str(int(round(float(calculated_data["data"]["percent"][skill_sort][:-1])/float(calculated_data["data"]["percent"][0][:-1]), 2)*100)) + "%",
+ "percent": calculated_data["data"]["percent"][skill_sort],
+ "count": calculated_data["data"]["counts"][skill_sort],
+ "value": calculated_data["data"]["damages"]
+ })
+ )
+ html = Template(read(VIEWS + "/jx3/calculator/calculator.html")).render(**{
+ "font": ASSETS + "/font/custom.ttf",
+ "yozai": ASSETS + "/font/Yozai-Medium.ttf",
+ "max": max_dps,
+ "avg": avg_dps,
+ "min": min_dps,
+ "tables": "\n".join(tables),
+ "school": "毒经",
+ "server": server,
+ "name": name,
+ "calculator": "【雾海寻龙】毒经DPS计算器 20240530"
+ })
+ final_html = CACHE + "/" + get_uuid() + ".html"
+ write(final_html, html)
+ final_path = await generate(final_html, False, "table", False)
+ if not isinstance(final_path, str):
+ return
+ return Path(final_path).as_uri()
\ No newline at end of file
diff --git a/src/plugins/jx3/calculator/universe.py b/src/plugins/jx3/calculator/universe.py
new file mode 100644
index 00000000..c5eafd7c
--- /dev/null
+++ b/src/plugins/jx3/calculator/universe.py
@@ -0,0 +1 @@
+from .dj import generate_calculator_img_dujing as dj_calculator
\ No newline at end of file
diff --git a/src/plugins/jx3/calendar/__init__.py b/src/plugins/jx3/calendar/__init__.py
index 51ff735b..3fc5178e 100644
--- a/src/plugins/jx3/calendar/__init__.py
+++ b/src/plugins/jx3/calendar/__init__.py
@@ -14,5 +14,7 @@ async def _(event: GroupMessageEvent, args: Message = CommandArg()):
if args.extract_plain_text() != "":
return
image = await getCalendar()
+ if not isinstance(image, str):
+ return
image = get_content_local(image)
await calendar.finish(ms.image(image))
\ No newline at end of file
diff --git a/src/plugins/jx3/jx3.py b/src/plugins/jx3/jx3.py
index 82bb09fc..314cc537 100644
--- a/src/plugins/jx3/jx3.py
+++ b/src/plugins/jx3/jx3.py
@@ -5,6 +5,7 @@
from .awesome import *
from .bind import *
from .buff import *
+from .calculator import *
from .calendar import *
from .daily import *
from .detail import *
diff --git a/src/plugins/jx3/serendipity/without_jx3api.py b/src/plugins/jx3/serendipity/without_jx3api.py
index 92d54fba..1804f3fe 100644
--- a/src/plugins/jx3/serendipity/without_jx3api.py
+++ b/src/plugins/jx3/serendipity/without_jx3api.py
@@ -1,10 +1,11 @@
from src.tools.config import Config
-from src.tools.utils.request import post_url, get_api
+from src.tools.utils.request import post_url, get_api, get_url
from src.tools.basic.jx3 import gen_ts, gen_xsk, format_body
from src.plugins.jx3.bind import get_player_local_data, Player
import json
+import re
ticket = Config.jx3.api.ticket
device_id = ticket.split("::")[-1]
@@ -22,6 +23,7 @@ class JX3Serendipity:
def __init__(self):
self.tl = []
self.my = []
+ self.jx3pet = []
def get_serendipity_level(self, serendipity_name: str) -> int:
if serendipity_name.find("宠物奇缘") != -1:
@@ -97,8 +99,24 @@ async def get_my_data(self, server: str, name: str):
}
serendipities.append(new)
self.my = serendipities
-
+
+ async def get_jx3pet_data(self, server: str, name: str):
+ final_url = f"https://www.jx3pet.com/api/serendipity?server={server}&type=不限&serendipity=不限&name={name}&limit=30"
+ data = await get_url(final_url)
+ data = json.loads(re.search(r'\{.*\}', data, re.DOTALL)[0]) # type: ignore
+ serendipities = []
+ for serendipity in data["data"]:
+ serendipities.append(
+ {
+ "name": serendipity["serendipity"],
+ "level": self.get_serendipity_level(serendipity["serendipity"]),
+ "time": serendipity["time"]
+ }
+ )
+ self.jx3pet = serendipities
+
async def integration(self, server: str, name: str):
await self.get_tuilan_data(server, name)
await self.get_my_data(server, name)
- return merge_dict_lists(self.tl, self.my)
\ No newline at end of file
+ await self.get_jx3pet_data(server, name)
+ return merge_dict_lists(self.jx3pet, merge_dict_lists(self.tl, self.my))
\ No newline at end of file
diff --git a/src/tools/utils/path.py b/src/tools/utils/path.py
index 7573ef2c..80772ad6 100644
--- a/src/tools/utils/path.py
+++ b/src/tools/utils/path.py
@@ -1,11 +1,11 @@
import os
-import pathlib2
+from pathlib import Path
tools_path = f"{os.getcwd()}/src/tools"
def get_path(path: str) -> str:
- t = pathlib2.Path(tools_path)
- return t.parent.joinpath(path).__str__()
+ t = Path(tools_path)
+ return str(t.parent.joinpath(path))
DATA = get_path("data")
CACHE = get_path("cache")
diff --git a/src/views/jx3/calculator/calculator.html b/src/views/jx3/calculator/calculator.html
new file mode 100644
index 00000000..dac1a398
--- /dev/null
+++ b/src/views/jx3/calculator/calculator.html
@@ -0,0 +1,167 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 技能 |
+ 占比 |
+ 次数 |
+ 伤害 |
+
+
+
+ {{ tables }}
+
+
+
+ © Inkar Suki · {{ school }}DPS计算器 · {{ server }} · {{ name }} ·
+ 06:41 计算器数据来源:{{ calculator }}
+ |
+
+
+
+
+
+
\ No newline at end of file