This commit is contained in:
qsc
2026-09-05 18:29:50 +08:00
parent bc4a38f589
commit 21033c8184
12 changed files with 146 additions and 58 deletions
+14
View File
@@ -1,5 +1,19 @@
## 更新记录 ## 更新记录
### version: 3.4.42026-09-05):
烟花查询在角色名称后新增可选的“条数”参数,默认展示前 50 条,支持指定正整数条数;沿用已绑定会话省略服务器的用法,并同步更新功能帮助和 README。上游接口未提供条数参数,查询结果在本地截取后生成图片。
修复绑定区服后,省略服务器并填写后续可选参数时被误判为显式服务器的问题;例如 `战绩 晏卿卿 22` 现在会正确补齐绑定区服,并按角色“晏卿卿”、模式“22”查询。
修复名剑战绩模板固定读取 `performance['3v3']`,导致 `22``55` 模式渲染失败的问题;现在会按查询模式分别使用 `2v2``3v3``5v5` 表现数据。
名剑战绩的对战记录按胜负统一整行文本颜色,胜利显示绿色,失败显示红色。
名剑排行榜的门派列复用名剑统计的图标样式,在门派名称前显示对应门派图标。
心法别名接入全局指令参数解析:试炼排行、阵眼、配装、技能、奇穴、小药和宏会在调用业务接口前将标准名称或别名统一转换为标准心法名;WebUI 保存或恢复别名后会立即刷新解析缓存,门派筛选参数保持原义。
### version: 3.4.32026-09-05): ### version: 3.4.32026-09-05):
接入 JX3API `POST /token/stats` 令牌统计接口,使用插件配置的 `jx3api_token` 查询等级、已用次数、剩余次数和有效状态;WebUI 顶部恢复为四项令牌统计,接口不可用或未配置令牌时显示未获取状态且不影响其他管理数据。 接入 JX3API `POST /token/stats` 令牌统计接口,使用插件配置的 `jx3api_token` 查询等级、已用次数、剩余次数和有效状态;WebUI 顶部恢复为四项令牌统计,接口不可用或未配置令牌时显示未获取状态且不影响其他管理数据。
+8 -6
View File
@@ -123,6 +123,7 @@ JX3API Token 可从 [JX3API](https://www.jx3api.com/) 获取。推栏 Ticket 通
- 缺少必填参数、数字转换失败或执行异常时,入口层统一回复 `参数错误或执行失败` - 缺少必填参数、数字转换失败或执行异常时,入口层统一回复 `参数错误或执行失败`
- 未绑定区服时按指令表提供标准参数。绑定后可以省略 `server` 参数;显式填写完整参数时仍优先使用本次输入的区服。在区服参数位置填写 `全区` 时,会忽略会话绑定并向接口传入空区服以查询全区数据。 - 未绑定区服时按指令表提供标准参数。绑定后可以省略 `server` 参数;显式填写完整参数时仍优先使用本次输入的区服。在区服参数位置填写 `全区` 时,会忽略会话绑定并向接口传入空区服以查询全区数据。
- 标准区服名和 WebUI 中配置的别名都可用于查询。对于区服后的可选参数,分发器通过当前有效区服目录和别名判断首个参数是显式区服还是后续参数。 - 标准区服名和 WebUI 中配置的别名都可用于查询。对于区服后的可选参数,分发器通过当前有效区服目录和别名判断首个参数是显式区服还是后续参数。
- 心法类指令会在入口层把标准心法名或 WebUI 配置的心法别名统一解析为标准名称;当前适用于试炼排行、阵眼、配装、技能、奇穴、小药和宏。门派筛选参数不参与心法别名解析。
### 会话区服绑定 ### 会话区服绑定
@@ -154,7 +155,7 @@ JX3API Token 可从 [JX3API](https://www.jx3api.com/) 获取。推栏 Ticket 通
| `关隘` | 查询关隘首领状态;图片 | Token | | `关隘` | 查询关隘首领状态;图片 | Token |
| `赤兔``本周赤兔` | 查询当日或本周赤兔记录;文本 | Token | | `赤兔``本周赤兔` | 查询当日或本周赤兔记录;文本 | Token |
| `阵营奉献 [阵营]` | 查询阵营奉献事件,固定最多 50 条;图片 | Token | | `阵营奉献 [阵营]` | 查询阵营奉献事件,固定最多 50 条;图片 | Token |
| `烟花 服务器 [角色]` | 查询指定服务器的烟花记录;已绑定会话可省略服务器;图片 | Token | | `烟花 服务器 角色 [条数]` | 查询指定服务器的烟花记录;条数默认为 50,须为正整数,填写时放在角色名称后;已绑定会话可省略服务器;图片 | Token |
| `刷马 服务器` | 查询刷马聊天情报;文本 | Token | | `刷马 服务器` | 查询刷马聊天情报;文本 | Token |
| `马场 服务器` | 查询未过期马场记录;文本 | Token | | `马场 服务器` | 查询未过期马场记录;文本 | Token |
@@ -162,7 +163,7 @@ JX3API Token 可从 [JX3API](https://www.jx3api.com/) 获取。推栏 Ticket 通
| 指令 | 说明与输出 | 凭据 | | 指令 | 说明与输出 | 凭据 |
| --- | --- | --- | | --- | --- | --- |
| `战绩 服务器 角色 [模式]` | 角色名剑战绩,模式默认 `33`;图片 | Token + Ticket | | `战绩 服务器 角色 [模式]` | 角色名剑战绩,模式可选 `22``33``55`默认 `33`;图片 | Token + Ticket |
| `名剑排行 [模式] [数量]` | 名剑大会排行,默认 `33`、50 条;图片 | Token + Ticket | | `名剑排行 [模式] [数量]` | 名剑大会排行,默认 `33`、50 条;图片 | Token + Ticket |
| `名剑统计 [模式]` | 名剑门派统计,模式默认 `33`;图片 | Token + Ticket | | `名剑统计 [模式]` | 名剑门派统计,模式默认 `33`;图片 | Token + Ticket |
| `帮会排行 服务器` | 回复序号选择神兵宝甲或爱心帮会榜单,最多保留前 50 条;图片 | Token | | `帮会排行 服务器` | 回复序号选择神兵宝甲或爱心帮会榜单,最多保留前 50 条;图片 | Token |
@@ -348,8 +349,9 @@ flowchart LR
1. `parse_message()` 检查前缀并使用 `str.split()` 切分消息。 1. `parse_message()` 检查前缀并使用 `str.split()` 切分消息。
2. 第一段作为指令,其余段作为位置参数。 2. 第一段作为指令,其余段作为位置参数。
3. `command_map` 将中文触发词映射到 `MessageBuilder` 方法。 3. `command_map` 将中文触发词映射到 `MessageBuilder` 方法。
4. `_call_with_auto_args()` 通过 `inspect.signature()` 读取参数签名,按注解转换 `int``float` 4. `_prepare_server_args()` `_prepare_kungfu_args()` 根据处理器参数名统一补齐区服绑定并解析区服、心法别名
5. 找不到指令时忽略消息;找到指令后停止事件继续传播并调用处理器 5. `_call_with_auto_args()` 通过 `inspect.signature()` 读取参数签名,按注解转换 `int``float`
6. 找不到指令时忽略消息;找到指令后停止事件继续传播并调用处理器。
分发器不会检查多余参数,多出的参数会被忽略。缺少必填参数会抛出异常并返回统一错误提示。 分发器不会检查多余参数,多出的参数会被忽略。缺少必填参数会抛出异常并返回统一错误提示。
@@ -474,7 +476,7 @@ astrbot_plugin_jx3/
│ ├── session_control.py # 全部会话、白名单与黑名单访问策略 │ ├── session_control.py # 全部会话、白名单与黑名单访问策略
│ ├── webui.py # 插件管理页路由、数据聚合与请求处理 │ ├── webui.py # 插件管理页路由、数据聚合与请求处理
│ ├── server_binding.py # 会话区服绑定、别名与区服目录 │ ├── server_binding.py # 会话区服绑定、别名与区服目录
│ ├── kungfu_alias.py # 本地心法目录初始化、校验与 WebUI 写入 │ ├── kungfu_alias.py # 本地心法目录初始化、全局别名解析、校验与 WebUI 写入
│ ├── bilei_data.py # 避雷数据增删改查 │ ├── bilei_data.py # 避雷数据增删改查
│ ├── sqlite.py # aiosqlite 通用封装 │ ├── sqlite.py # aiosqlite 通用封装
│ ├── fun_basic.py # 图标、时间和货币格式化工具 │ ├── fun_basic.py # 图标、时间和货币格式化工具
@@ -520,7 +522,7 @@ git diff --check
## 当前版本状态 ## 当前版本状态
以下内容是对 v3.4.3 当前源码的静态核对结果,部署和二次开发前应注意: 以下内容是对 v3.4.4 当前源码的静态核对结果,部署和二次开发前应注意:
1. 查询图片使用浅色高对比主题和放大的内容区域;渲染清晰度、JPEG/PNG 格式及 JPEG 质量由 `image_render_quality` 配置组控制,提高清晰度或使用 PNG 会增加图片体积与渲染耗时。 1. 查询图片使用浅色高对比主题和放大的内容区域;渲染清晰度、JPEG/PNG 格式及 JPEG 质量由 `image_render_quality` 配置组控制,提高清晰度或使用 PNG 会增加图片体积与渲染耗时。
2. `帮会排行``阵营排行``其他排行` 使用固定的“数字序号 → 榜单名称”首轮菜单,次轮查询统一截取接口返回的前 50 条;取得有效选择后会先停止超时计时器,避免渲染期间重复输出。 2. `帮会排行``阵营排行``其他排行` 使用固定的“数字序号 → 榜单名称”首轮菜单,次轮查询统一截取接口返回的前 50 条;取得有效选择后会先停止超时计时器,避免渲染期间重复输出。
+9 -2
View File
@@ -451,10 +451,11 @@ class JX3APIService:
) )
async def yanhuachaxun(self, server: str, name:str ) -> Dict[str, Any]: async def yanhuachaxun(self, server: str, name: str, limit: int) -> Dict[str, Any]:
"""烟花记录""" """烟花记录"""
# 数据处理 # 数据处理
async def processor(data: Any, return_data: Dict[str, Any]) -> None: async def processor(data: Any, return_data: Dict[str, Any]) -> None:
data = data[:limit]
for item in data: for item in data:
item["time"] = format_time(item.get("time")) item["time"] = format_time(item.get("time"))
@@ -511,7 +512,13 @@ class JX3APIService:
async def zhanji(self, name: str, server:str, mode:str) -> Dict[str, Any]: async def zhanji(self, name: str, server:str, mode:str) -> Dict[str, Any]:
"""战绩""" """战绩"""
# 数据处理 # 数据处理
async def processor(data: Any, return_data: Dict[str, Any]) -> None: async def processor(data: Any, return_data: Dict[str, Any]) -> None:
performance_key = {
"22": "2v2",
"33": "3v3",
"55": "5v5",
}.get(str(mode), "3v3")
data["currentPerformance"] = data["performance"][performance_key]
return_data["data"] = data return_data["data"] = data
return await self._request_api( return await self._request_api(
+33
View File
@@ -13,6 +13,7 @@ class KungfuAliasService:
def __init__(self, sqlite: AsyncSQLiteDB, seed_path: Path): def __init__(self, sqlite: AsyncSQLiteDB, seed_path: Path):
self.sql = sqlite self.sql = sqlite
self.seed_path = seed_path self.seed_path = seed_path
self._kungfu_lookup: dict[str, str] = {}
async def initialize(self): async def initialize(self):
await self.sql.execute( await self.sql.execute(
@@ -29,6 +30,7 @@ class KungfuAliasService:
""" """
) )
await self._seed_defaults() await self._seed_defaults()
await self._reload_cache()
async def _seed_defaults(self): async def _seed_defaults(self):
records = self._load_seed_defaults() records = self._load_seed_defaults()
@@ -84,6 +86,7 @@ class KungfuAliasService:
for values in records for values in records
) )
await self.sql.execute_transaction(statements) await self.sql.execute_transaction(statements)
await self._reload_cache()
return len(records) return len(records)
async def list_kungfu(self) -> list[dict[str, Any]]: async def list_kungfu(self) -> list[dict[str, Any]]:
@@ -141,6 +144,36 @@ class KungfuAliasService:
""", """,
(*values, normalized_pzid), (*values, normalized_pzid),
) )
await self._reload_cache()
async def _reload_cache(self):
"""Refresh the canonical kungfu name and alias lookup cache.
Returns:
None.
"""
rows = await self.list_kungfu()
lookup = {
self._key(row["name"]): row["name"]
for row in rows
if row["name"]
}
for row in rows:
for alias in row["aliases"]:
lookup.setdefault(self._key(alias), row["name"])
self._kungfu_lookup = lookup
def resolve_kungfu(self, value: Any) -> str:
"""Resolve a canonical kungfu name or alias to its canonical name.
Args:
value: Canonical kungfu name or configured alias.
Returns:
Canonical kungfu name when matched; otherwise the cleaned input.
"""
kungfu = self._clean(value)
return self._kungfu_lookup.get(self._key(kungfu), kungfu)
def _normalize_aliases(self, name: str, aliases: Iterable[Any]) -> list[str]: def _normalize_aliases(self, name: str, aliases: Iterable[Any]) -> list[str]:
result: list[str] = [] result: list[str] = []
+22 -18
View File
@@ -321,9 +321,13 @@ class MessageBuilder:
""" 阵营事件 阵营""" """ 阵营事件 阵营"""
return await self.T2I_image_msg(event, lambda: self.jx3api.zhenyingevent(name,50)) return await self.T2I_image_msg(event, lambda: self.jx3api.zhenyingevent(name,50))
async def yanhuachaxun(self, event: AstrMessageEvent,server: str,name: str = "" ): async def yanhuachaxun(self, event: AstrMessageEvent, server: str, name: str = "", limit: int = 50):
""" 烟花 服务器 角色""" """ 烟花 服务器 角色 条数"""
return await self.T2I_image_msg(event, lambda: self.jx3api.yanhuachaxun(server,name)) if limit <= 0:
return event.plain_result("条数必须为正整数")
return await self.T2I_image_msg(
event, lambda: self.jx3api.yanhuachaxun(server, name, limit)
)
async def shuma(self, event: AstrMessageEvent,server: str ): async def shuma(self, event: AstrMessageEvent,server: str ):
""" 刷马 服务器""" """ 刷马 服务器"""
@@ -369,9 +373,9 @@ class MessageBuilder:
lambda selected: self.jx3api.rank_statistical_select(server,selected,), lambda selected: self.jx3api.rank_statistical_select(server,selected,),
) )
async def shilianpaixing(self, event: AstrMessageEvent, server: str , name: str): async def shilianpaixing(self, event: AstrMessageEvent, server: str , kungfu: str):
""" 试炼排行 服务器 心法 """ """ 试炼排行 服务器 心法 """
return await self.T2I_image_msg(event, lambda: self.jx3api.shilianpaixing(name, server)) return await self.T2I_image_msg(event, lambda: self.jx3api.shilianpaixing(kungfu, server))
async def zhengyingpaimai(self, event: AstrMessageEvent,server: str , name: str = "", limit: int = 50 ): async def zhengyingpaimai(self, event: AstrMessageEvent,server: str , name: str = "", limit: int = 50 ):
""" 阵营拍卖 物品名称 服务器""" """ 阵营拍卖 物品名称 服务器"""
@@ -465,25 +469,25 @@ class MessageBuilder:
""" 角色 服务器 名称 """ """ 角色 服务器 名称 """
return await self.plain_msg(event, lambda: self.jx3api.jueshe(server, name, 1)) return await self.plain_msg(event, lambda: self.jx3api.jueshe(server, name, 1))
async def zhenyan(self, event: AstrMessageEvent, name: str): async def zhenyan(self, event: AstrMessageEvent, kungfu: str):
""" 阵眼 心法""" """ 阵眼 心法"""
return await self.plain_msg(event, lambda: self.jx3api.zhenyan(name)) return await self.plain_msg(event, lambda: self.jx3api.zhenyan(kungfu))
async def peizhuang(self, event: AstrMessageEvent,name: str, tags: str = ""): async def peizhuang(self, event: AstrMessageEvent, kungfu: str, tags: str = ""):
""" 配装 心法 类型""" """ 配装 心法 类型"""
return await self.plain_msg(event, lambda: self.jx3box.peizhuang(name,tags)) return await self.plain_msg(event, lambda: self.jx3box.peizhuang(kungfu,tags))
async def zilipaixing(self, event: AstrMessageEvent, server: str = "", school: str = ""): async def zilipaixing(self, event: AstrMessageEvent, server: str = "", school: str = ""):
""" 资历排行 服务器 门派 """ """ 资历排行 服务器 门派 """
return await self.T2I_image_msg(event, lambda: self.jx3api.zilipaixing(server, school)) return await self.T2I_image_msg(event, lambda: self.jx3api.zilipaixing(server, school))
async def jineng(self, event: AstrMessageEvent, name: str): async def jineng(self, event: AstrMessageEvent, kungfu: str):
""" 技能 心法""" """ 技能 心法"""
return await self.T2I_image_msg(event, lambda: self.jx3api.jineng(name,0)) return await self.T2I_image_msg(event, lambda: self.jx3api.jineng(kungfu,0))
async def qixue(self, event: AstrMessageEvent, name: str): async def qixue(self, event: AstrMessageEvent, kungfu: str):
""" 奇穴 心法""" """ 奇穴 心法"""
return await self.T2I_image_msg(event, lambda: self.jx3api.qixue(name,0)) return await self.T2I_image_msg(event, lambda: self.jx3api.qixue(kungfu,0))
async def liaotian(self, event: AstrMessageEvent, server:str, name: str, limit:int = 20, page:int = 1): async def liaotian(self, event: AstrMessageEvent, server:str, name: str, limit:int = 20, page:int = 1):
""" 发言 服务器 角色 条数 页数""" """ 发言 服务器 角色 条数 页数"""
@@ -493,9 +497,9 @@ class MessageBuilder:
""" 统战 服务器""" """ 统战 服务器"""
return await self.plain_msg(event, lambda: self.jx3api.tongzhanyy(server)) return await self.plain_msg(event, lambda: self.jx3api.tongzhanyy(server))
async def xiaoyao(self, event: AstrMessageEvent, name:str = ""): async def xiaoyao(self, event: AstrMessageEvent, kungfu:str = ""):
""" 小药 心法""" """ 小药 心法"""
return await self.T2I_image_msg(event, lambda: self.jx3api.xiaoyao(name)) return await self.T2I_image_msg(event, lambda: self.jx3api.xiaoyao(kungfu))
async def pianzhi(self, event: AstrMessageEvent, uid: str, server:str = ""): async def pianzhi(self, event: AstrMessageEvent, uid: str, server:str = ""):
""" 骗子 uid 服务器""" """ 骗子 uid 服务器"""
@@ -618,12 +622,12 @@ class MessageBuilder:
return await self.T2I_image_msg(event, lambda: self.jx3api.diaoluo(name, server, limit)) return await self.T2I_image_msg(event, lambda: self.jx3api.diaoluo(name, server, limit))
async def hong(self, event: AstrMessageEvent,name: str): async def hong(self, event: AstrMessageEvent, kungfu: str):
""" 宏 心法""" """ 宏 心法"""
return await self.handler_plain_image_msg( return await self.handler_plain_image_msg(
event, event,
lambda: self.jx3box.hong1(name), lambda: self.jx3box.hong1(kungfu),
lambda selected: self.jx3box.hong_select(name, selected), lambda selected: self.jx3box.hong_select(kungfu, selected),
result_handler=self.plain_image_msg, result_handler=self.plain_image_msg,
) )
+30 -14
View File
@@ -25,7 +25,7 @@ PLUGIN_NAME = "astrbot_plugin_jx3"
@register("astrbot_plugin_jx3", @register("astrbot_plugin_jx3",
"fxdyz", "fxdyz",
"聚合剑网三游戏数据,提供查询、图片渲染、本地避雷和实时事件推送。", "聚合剑网三游戏数据,提供查询、图片渲染、本地避雷和实时事件推送。",
"3.4.3", "3.4.4",
"https://github.com/qsc20001102/astrbot_plugin_jx3" "https://github.com/qsc20001102/astrbot_plugin_jx3"
) )
class Jx3ApiPlugin(Star): class Jx3ApiPlugin(Star):
@@ -407,14 +407,6 @@ class Jx3ApiPlugin(Star):
has_server_arg = server_index < len(prepared) has_server_arg = server_index < len(prepared)
if bound_server: if bound_server:
required_count = sum(
parameter.default is inspect.Parameter.empty
for parameter in params
)
has_required_parameter_after_server = any(
parameter.default is inspect.Parameter.empty
for parameter in params[server_index + 1:]
)
explicit_server = ( explicit_server = (
has_server_arg has_server_arg
and ( and (
@@ -422,11 +414,6 @@ class Jx3ApiPlugin(Star):
prepared[server_index] prepared[server_index]
) )
or self.server_binding.is_known_server(prepared[server_index]) or self.server_binding.is_known_server(prepared[server_index])
or len(prepared) >= len(params)
or (
has_required_parameter_after_server
and len(prepared) >= required_count
)
) )
) )
if explicit_server: if explicit_server:
@@ -442,6 +429,34 @@ class Jx3ApiPlugin(Star):
return prepared return prepared
def _prepare_kungfu_args(self, handler, args: list[str]) -> list[str]:
"""Resolve the kungfu parameter through the global alias catalog.
Args:
handler: Command handler whose signature defines argument positions.
args: Positional command arguments after server preparation.
Returns:
Arguments with a recognized kungfu alias replaced by its canonical name.
"""
params = [
parameter
for parameter in inspect.signature(handler).parameters.values()
if parameter.name not in {"self", "event"}
]
kungfu_index = next(
(index for index, parameter in enumerate(params) if parameter.name == "kungfu"),
None,
)
if kungfu_index is None or kungfu_index >= len(args):
return args
prepared = list(args)
prepared[kungfu_index] = self.kungfu_alias.resolve_kungfu(
prepared[kungfu_index]
)
return prepared
async def _call_with_auto_args(self, handler, event: AstrMessageEvent, args: list[str]): async def _call_with_auto_args(self, handler, event: AstrMessageEvent, args: list[str]):
"""指令执行函数""" """指令执行函数"""
@@ -511,6 +526,7 @@ class Jx3ApiPlugin(Star):
try: try:
args = await self._prepare_server_args(handler, event, args) args = await self._prepare_server_args(handler, event, args)
args = self._prepare_kungfu_args(handler, args)
ret = await self._call_with_auto_args(handler, event, args) ret = await self._call_with_auto_args(handler, event, args)
if ret is not None: if ret is not None:
yield ret yield ret
+1 -1
View File
@@ -1,7 +1,7 @@
name: astrbot_plugin_jx3 name: astrbot_plugin_jx3
display_name: 剑网三游戏数据查询工具 display_name: 剑网三游戏数据查询工具
desc: 聚合剑网三游戏数据,提供查询、图片渲染、本地避雷和实时事件推送。 desc: 聚合剑网三游戏数据,提供查询、图片渲染、本地避雷和实时事件推送。
version: 3.4.3 version: 3.4.4
author: 飞翔大野猪 author: 飞翔大野猪
repo: https://github.com/qsc20001102/astrbot_plugin_jx3 repo: https://github.com/qsc20001102/astrbot_plugin_jx3
astrbot_version: ">=4.24.1" astrbot_version: ">=4.24.1"
+1 -1
View File
@@ -24,7 +24,7 @@
<div class="command-row"><div class="feature-name">关隘首领</div><div class="commands"><code class="command">关隘</code></div></div> <div class="command-row"><div class="feature-name">关隘首领</div><div class="commands"><code class="command">关隘</code></div></div>
<div class="command-row"><div class="feature-name">赤兔记录</div><div class="commands"><code class="command">赤兔</code><code class="command">本周赤兔</code></div></div> <div class="command-row"><div class="feature-name">赤兔记录</div><div class="commands"><code class="command">赤兔</code><code class="command">本周赤兔</code></div></div>
<div class="command-row"><div class="feature-name">阵营事件</div><div class="commands"><code class="command">阵营奉献 [阵营]</code></div></div> <div class="command-row"><div class="feature-name">阵营事件</div><div class="commands"><code class="command">阵营奉献 [阵营]</code></div></div>
<div class="command-row"><div class="feature-name">烟花记录</div><div class="commands"><code class="command">烟花 服务器 角色</code></div></div> <div class="command-row" data-description="条数默认为 50,须为正整数"><div class="feature-name">烟花记录</div><div class="commands"><code class="command">烟花 服务器 [角色] [条数]</code></div></div>
<div class="command-row"><div class="feature-name">马场查询</div><div class="commands"><code class="command">刷马 服务器</code><code class="command">马场 服务器</code></div></div> <div class="command-row"><div class="feature-name">马场查询</div><div class="commands"><code class="command">刷马 服务器</code><code class="command">马场 服务器</code></div></div>
</div> </div>
</section> </section>
+9 -5
View File
@@ -11,7 +11,6 @@
<th>排名</th> <th>排名</th>
<th>头像</th> <th>头像</th>
<th>角色</th> <th>角色</th>
<th>区服</th>
<th>门派</th> <th>门派</th>
<th>分数</th> <th>分数</th>
<th>胜率</th> <th>胜率</th>
@@ -35,11 +34,16 @@
<td>{{ m.roleName }}</td> <td>{{ m.roleName }}</td>
<td>{{ m.zoneName }} · {{ m.serverName }}</td> <td>
<div class="icon-label">
{% if icons.sect.get(m.forceName) %}
<img class="icon-label__icon" src="{{ icons.sect[m.forceName] }}" alt="{{ m.forceName }}">
{% endif %}
<span>{{ m.forceName }}</span>
</div>
</td>
<td>{{ m.forceName }}</td> <td>{{ m.matchScore }}</td>
<td>{{ m.score }}</td>
<td class="winrate data-cell--numeric">{{ m.winRate }}</td> <td class="winrate data-cell--numeric">{{ m.winRate }}</td>
</tr> </tr>
+4 -4
View File
@@ -21,10 +21,10 @@
{% for item in items %} {% for item in items %}
<tr> <tr>
<td class="data-cell--rank">{{ loop.index }}</td> <td class="data-cell--rank">{{ loop.index }}</td>
<td class="data-cell--name">{{ item.role_name }}</td> <td class="data-cell--name">{{ item.roleName }}</td>
<td class="data-cell--nowrap data-cell--numeric">{{ item.equip_score }}</td> <td class="data-cell--nowrap data-cell--numeric">{{ item.equipScore }}</td>
<td class="data-cell--nowrap data-cell--numeric">{{ item.max_level }}</td> <td class="data-cell--nowrap data-cell--numeric">{{ item.maxLevel }}</td>
<td class="data-cell--score">{{ item.total_score }}</td> <td class="data-cell--score">{{ item.totalScore }}</td>
</tr> </tr>
{% endfor %} {% endfor %}
</tbody> </tbody>
+7 -7
View File
@@ -16,34 +16,34 @@
</div> </div>
</div> </div>
<!-- 头像 + 当前 3v3 表现 --> <!-- 当前查询模式表现 -->
<div class="stats-wrap"> <div class="stats-wrap">
<!-- 右侧数据 --> <!-- 右侧数据 -->
<div class="stats"> <div class="stats">
<div class="stat-box"> <div class="stat-box">
<div class="stat-title">名剑积分</div> <div class="stat-title">名剑积分</div>
<div class="stat-value mmr">{{ performance['3v3'].mmr }}</div> <div class="stat-value mmr">{{ currentPerformance.mmr }}</div>
</div> </div>
<div class="stat-box"> <div class="stat-box">
<div class="stat-title">名剑段位</div> <div class="stat-title">名剑段位</div>
<div class="stat-value">{{ performance['3v3'].grade }}</div> <div class="stat-value">{{ currentPerformance.grade }}</div>
</div> </div>
<div class="stat-box"> <div class="stat-box">
<div class="stat-title">胜率</div> <div class="stat-title">胜率</div>
<div class="stat-value winrate">{{ performance['3v3'].winRate }}%</div> <div class="stat-value winrate">{{ currentPerformance.winRate }}%</div>
</div> </div>
<div class="stat-box"> <div class="stat-box">
<div class="stat-title">总场数</div> <div class="stat-title">总场数</div>
<div class="stat-value">{{ performance['3v3'].totalCount }}</div> <div class="stat-value">{{ currentPerformance.totalCount }}</div>
</div> </div>
<div class="stat-box"> <div class="stat-box">
<div class="stat-title">MVP次数</div> <div class="stat-title">MVP次数</div>
<div class="stat-value">{{ performance['3v3'].mvpCount }}</div> <div class="stat-value">{{ currentPerformance.mvpCount }}</div>
</div> </div>
</div> </div>
@@ -66,7 +66,7 @@
<tbody> <tbody>
{% for m in history %} {% for m in history %}
<tr> <tr class="{{ 'match-win' if m.won else 'match-lose' }}">
<td class="time-col start-time" data-ts="{{ m.startTime }}">{{ m.startTime }}</td> <td class="time-col start-time" data-ts="{{ m.startTime }}">{{ m.startTime }}</td>
<td class="duration-col">{{ m.endTime - m.startTime }}</td> <td class="duration-col">{{ m.endTime - m.startTime }}</td>
<td class="kungfu-col">{{ m.kungfu }}</td> <td class="kungfu-col">{{ m.kungfu }}</td>
+8
View File
@@ -83,6 +83,14 @@
font-weight: bold; font-weight: bold;
} }
.data-table tr.match-win > td {
color: var(--jx3-green);
}
.data-table tr.match-lose > td {
color: var(--jx3-red);
}
.mvp { .mvp {
color: #f5a623; color: #f5a623;
font-weight: bold; font-weight: bold;