koishi-plugin-rocom 1.0.8 → 1.0.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/client.d.ts +4 -2
- package/lib/client.js +18 -17
- package/lib/commands/query.js +0 -63
- package/lib/index.js +1 -2
- package/lib/render-templates/player-search/index.html +68 -60
- package/lib/render-templates/player-search/style.css +300 -192
- package/lib/render.js +0 -3
- package/package.json +1 -1
- package/readme.md +3 -4
- package/lib/render-templates/student/index.html +0 -95
- package/lib/render-templates/student/style.css +0 -255
- package/lib/render-templates/student-perks/index.html +0 -78
- package/lib/render-templates/student-perks/style.css +0 -238
- package/lib/render-templates/student-state/index.html +0 -52
- package/lib/render-templates/student-state/style.css +0 -157
package/lib/client.d.ts
CHANGED
|
@@ -51,8 +51,10 @@ export declare class RocomClient {
|
|
|
51
51
|
ingameHomeInfo(ctx: Context, uid: string, waitMs?: number): Promise<any>;
|
|
52
52
|
ingameMerchantInfo(ctx: Context, shopId: string | number): Promise<any>;
|
|
53
53
|
getFriendship(ctx: Context, fwToken: string, userIds: string, userIdentifier?: string): Promise<any>;
|
|
54
|
-
getStudentState(ctx: Context, fwToken: string, accountType?: number, userIdentifier?: string): Promise<any>;
|
|
55
|
-
getStudentPerks(ctx: Context, fwToken: string, area?: number, accountType?: number, userIdentifier?: string): Promise<any>;
|
|
56
54
|
searchWikiPet(ctx: Context, query: string, limit?: number): Promise<any>;
|
|
57
55
|
searchWikiSkill(ctx: Context, query: string, limit?: number): Promise<any>;
|
|
56
|
+
getWikiPetDetail(ctx: Context, options: {
|
|
57
|
+
id?: number;
|
|
58
|
+
name?: string;
|
|
59
|
+
}): Promise<any>;
|
|
58
60
|
}
|
package/lib/client.js
CHANGED
|
@@ -99,6 +99,9 @@ class RocomClient {
|
|
|
99
99
|
if (/缺少\s*API\s*Key|API\s*Key.*required|missing\s+api\s*key/i.test(message)) {
|
|
100
100
|
return true;
|
|
101
101
|
}
|
|
102
|
+
if (/请提供有效的认证凭证|有效的?认证凭证|valid\s+credentials?\s+required|X-API-Key|Authorization\s*:\s*Bearer|X-Anonymous-Token/i.test(message)) {
|
|
103
|
+
return true;
|
|
104
|
+
}
|
|
102
105
|
if (/HTTP\s*(401|403)/i.test(message)) {
|
|
103
106
|
return true;
|
|
104
107
|
}
|
|
@@ -280,7 +283,11 @@ class RocomClient {
|
|
|
280
283
|
const status = Number(response?.status ?? response?.statusCode ?? 200);
|
|
281
284
|
const body = response?.data !== undefined ? response.data : response;
|
|
282
285
|
if (body?.code !== undefined && body.code !== 0) {
|
|
283
|
-
|
|
286
|
+
const rawMessage = body.message || body.msg || '接口返回异常';
|
|
287
|
+
const message = !acceptedStatuses.includes(status)
|
|
288
|
+
? `HTTP ${status}: ${rawMessage}`
|
|
289
|
+
: rawMessage;
|
|
290
|
+
this.setLastError(message);
|
|
284
291
|
if (!options.silentFailureDetails) {
|
|
285
292
|
this.logRequestFailureDetails(method, path, headers, options.params, options.json, body);
|
|
286
293
|
}
|
|
@@ -509,25 +516,19 @@ class RocomClient {
|
|
|
509
516
|
async getFriendship(ctx, fwToken, userIds, userIdentifier = '') {
|
|
510
517
|
return this.get(ctx, '/api/v1/games/rocom/social/friendship', this.rocomHeaders(fwToken, userIdentifier), { user_ids: userIds });
|
|
511
518
|
}
|
|
512
|
-
async getStudentState(ctx, fwToken, accountType, userIdentifier = '') {
|
|
513
|
-
const params = {};
|
|
514
|
-
if (accountType !== undefined)
|
|
515
|
-
params.account_type = accountType;
|
|
516
|
-
return this.get(ctx, '/api/v1/games/rocom/activity/student-state', this.rocomHeaders(fwToken, userIdentifier), params);
|
|
517
|
-
}
|
|
518
|
-
async getStudentPerks(ctx, fwToken, area, accountType, userIdentifier = '') {
|
|
519
|
-
const params = {};
|
|
520
|
-
if (area !== undefined)
|
|
521
|
-
params.area = area;
|
|
522
|
-
if (accountType !== undefined)
|
|
523
|
-
params.account_type = accountType;
|
|
524
|
-
return this.get(ctx, '/api/v1/games/rocom/activity/perks', this.rocomHeaders(fwToken, userIdentifier), params);
|
|
525
|
-
}
|
|
526
519
|
async searchWikiPet(ctx, query, limit = 10) {
|
|
527
|
-
return this.get(ctx, '/api/v1/games/rocom/
|
|
520
|
+
return this.get(ctx, '/api/v1/games/rocom/pet/list', this.wegameHeaders(), { q: query, page_size: limit });
|
|
528
521
|
}
|
|
529
522
|
async searchWikiSkill(ctx, query, limit = 10) {
|
|
530
|
-
return this.get(ctx, '/api/v1/games/rocom/
|
|
523
|
+
return this.get(ctx, '/api/v1/games/rocom/pet/skill-users', this.wegameHeaders(), { skill: query, limit });
|
|
524
|
+
}
|
|
525
|
+
async getWikiPetDetail(ctx, options) {
|
|
526
|
+
const params = {};
|
|
527
|
+
if (options.id !== undefined)
|
|
528
|
+
params.id = options.id;
|
|
529
|
+
if (options.name)
|
|
530
|
+
params.name = options.name;
|
|
531
|
+
return this.get(ctx, '/api/v1/games/rocom/pet/detail', this.wegameHeaders(), params);
|
|
531
532
|
}
|
|
532
533
|
}
|
|
533
534
|
exports.RocomClient = RocomClient;
|
package/lib/commands/query.js
CHANGED
|
@@ -1058,12 +1058,6 @@ function buildPlayerSearchRenderData(payload, uid) {
|
|
|
1058
1058
|
['舒适度', playerField(parsed, 'home_comfort_level')],
|
|
1059
1059
|
['访客数量', playerField(parsed, 'visitor_num')],
|
|
1060
1060
|
]),
|
|
1061
|
-
pack('名片信息', [
|
|
1062
|
-
['名片皮肤', playerField(parsed, 'card_skin_selected')],
|
|
1063
|
-
['名片头像', playerField(parsed, 'card_icon_selected')],
|
|
1064
|
-
['首标签', playerField(parsed, 'card_label_first_selected')],
|
|
1065
|
-
['尾标签', playerField(parsed, 'card_label_last_selected')],
|
|
1066
|
-
]),
|
|
1067
1061
|
].filter(Boolean);
|
|
1068
1062
|
const summaryCards = [
|
|
1069
1063
|
{ label: '等级', value: parsed.level },
|
|
@@ -1076,7 +1070,6 @@ function buildPlayerSearchRenderData(payload, uid) {
|
|
|
1076
1070
|
const signature = parsed.signature && parsed.signature !== '未设置' ? parsed.signature : '';
|
|
1077
1071
|
return {
|
|
1078
1072
|
title: '洛克玩家',
|
|
1079
|
-
subtitle: parsed.title,
|
|
1080
1073
|
heroTitle: '玩家信息',
|
|
1081
1074
|
heroValue: parsed.nickname,
|
|
1082
1075
|
heroSubvalue: `UID ${parsed.uid}`,
|
|
@@ -1160,45 +1153,6 @@ function buildFriendshipRenderData(payload, userIds) {
|
|
|
1160
1153
|
copyright: 'Koishi & WeGame Locke Kingdom Plugin',
|
|
1161
1154
|
};
|
|
1162
1155
|
}
|
|
1163
|
-
function buildStudentRenderData(statePayload, perksPayload, area, accountType) {
|
|
1164
|
-
const school = statePayload?.school || statePayload?.school_name || '未返回';
|
|
1165
|
-
const certified = String(statePayload?.certified) === '1';
|
|
1166
|
-
const cards = perksPayload?.cards || [];
|
|
1167
|
-
return {
|
|
1168
|
-
title: '洛克学生',
|
|
1169
|
-
subtitle: `大区:${area} 账号类型:${accountTypeText(accountType)}`,
|
|
1170
|
-
heroTitle: '学生信息总览',
|
|
1171
|
-
heroValue: certified ? '已通过' : '未认证',
|
|
1172
|
-
heroSubvalue: school,
|
|
1173
|
-
summaryCards: [
|
|
1174
|
-
{ label: '认证状态', value: certified ? '已认证' : '未认证' },
|
|
1175
|
-
{ label: '学校', value: school },
|
|
1176
|
-
{ label: '奖励数量', value: String(cards.length) },
|
|
1177
|
-
],
|
|
1178
|
-
stateItems: [
|
|
1179
|
-
{ label: '学生认证', value: certified ? '是' : '否' },
|
|
1180
|
-
{ label: '游戏内认证', value: String(statePayload?.game_certified) === '1' ? '是' : '否' },
|
|
1181
|
-
{ label: '学校', value: school },
|
|
1182
|
-
{ label: '上游状态', value: statePayload?.result?.error_message || 'WG_COMM_SUCC' },
|
|
1183
|
-
{ label: '上游错误码', value: stringifyInspectValue(statePayload?.result?.error_code || 0) },
|
|
1184
|
-
],
|
|
1185
|
-
perkCards: cards.map((card) => ({
|
|
1186
|
-
name: card.name || `奖励 #${card.id || '-'}`,
|
|
1187
|
-
count: card.count || 0,
|
|
1188
|
-
desc: card.desc || '暂无说明',
|
|
1189
|
-
icon: card.icon || '',
|
|
1190
|
-
id: stringifyInspectValue(card.id),
|
|
1191
|
-
stateText: `状态码 ${stringifyInspectValue(card.state)}`,
|
|
1192
|
-
})),
|
|
1193
|
-
detailItems: Object.entries(perksPayload || {})
|
|
1194
|
-
.filter(([key, value]) => !['cards', 'result'].includes(key) && (value === null || typeof value !== 'object'))
|
|
1195
|
-
.map(([key, value]) => ({ label: key.replace(/_/g, ' '), value: stringifyInspectValue(value) })),
|
|
1196
|
-
stateResult: statePayload?.result?.error_message || 'WG_COMM_SUCC',
|
|
1197
|
-
perksResult: perksPayload?.result?.error_message || 'WG_COMM_SUCC',
|
|
1198
|
-
commandHint: '洛克.学生 [area] [account_type]',
|
|
1199
|
-
copyright: 'Koishi & WeGame Locke Kingdom Plugin',
|
|
1200
|
-
};
|
|
1201
|
-
}
|
|
1202
1156
|
function sessionTarget(session) {
|
|
1203
1157
|
return {
|
|
1204
1158
|
platform: session?.platform || session?.bot?.platform || '',
|
|
@@ -1873,23 +1827,6 @@ function register(deps) {
|
|
|
1873
1827
|
return `好友关系查询失败:${client.getLastErrorBrief()}`;
|
|
1874
1828
|
await sendImage(deps, session, 'friendship', buildFriendshipRenderData(res, userIds), `【好友关系】${userIds}`);
|
|
1875
1829
|
});
|
|
1876
|
-
ctx.command('洛克').subcommand('.学生 [area:number] [accountType:number]', '查询学生认证状态与学生活动福利')
|
|
1877
|
-
.alias('洛克学生')
|
|
1878
|
-
.action(async ({ session }, area = 101, accountType = 0) => {
|
|
1879
|
-
const fwToken = await (0, account_1.getPrimaryToken)(deps, session.userId);
|
|
1880
|
-
if (!fwToken)
|
|
1881
|
-
return (0, account_1.notLoggedInHint)();
|
|
1882
|
-
const userIdentifier = session.userId;
|
|
1883
|
-
const [stateRes, perksRes] = await Promise.all([
|
|
1884
|
-
client.getStudentState(ctx, fwToken, accountType, userIdentifier),
|
|
1885
|
-
client.getStudentPerks(ctx, fwToken, area, accountType, userIdentifier),
|
|
1886
|
-
]);
|
|
1887
|
-
if (!stateRes)
|
|
1888
|
-
return `学生认证状态查询失败:${client.getLastErrorBrief()}`;
|
|
1889
|
-
if (!perksRes)
|
|
1890
|
-
return `学生活动福利查询失败:${client.getLastErrorBrief()}`;
|
|
1891
|
-
await sendImage(deps, session, 'student', buildStudentRenderData(stateRes, perksRes, area, accountType), '【洛克学生】认证与福利信息');
|
|
1892
|
-
});
|
|
1893
1830
|
ctx.command('订阅家园菜园 [uid:string]', '订阅指定 UID 的家园菜园成熟提醒')
|
|
1894
1831
|
.action(async ({ session }, uid = '') => subscribeHome(deps, session, uid, 'garden'));
|
|
1895
1832
|
ctx.command('订阅家园灵感 [uid:string]', '订阅指定 UID 的家园精灵灵感完成提醒')
|
package/lib/index.js
CHANGED
|
@@ -51,7 +51,6 @@ const MENU_GROUPS = [
|
|
|
51
51
|
{ cmd: '洛克.家园', desc: '查询家园菜园' },
|
|
52
52
|
{ cmd: '洛克.商店', desc: '查询 ingame 商店' },
|
|
53
53
|
{ cmd: '洛克.好友关系', desc: '查询好友关系' },
|
|
54
|
-
{ cmd: '洛克.学生', desc: '查询学生认证与福利' },
|
|
55
54
|
],
|
|
56
55
|
},
|
|
57
56
|
{
|
|
@@ -96,7 +95,7 @@ function buildMenuFallbackText() {
|
|
|
96
95
|
exports.Config = koishi_1.Schema.intersect([
|
|
97
96
|
koishi_1.Schema.object({
|
|
98
97
|
apiBaseUrl: koishi_1.Schema.string().default('https://wegame.shallow.ink').description('API 基础地址'),
|
|
99
|
-
wegameApiKey: koishi_1.Schema.string().default('').description('WeGame API Key'),
|
|
98
|
+
wegameApiKey: koishi_1.Schema.string().default('').description('WeGame API Key(获取 key 查看 Github:https://github.com/Entropy-Increase-Team/koishi-plugin-rocom )'),
|
|
100
99
|
qqLoginDebugMode: koishi_1.Schema.boolean().default(false).description('QQ 扫码登录调试模式,仅调试时开启'),
|
|
101
100
|
adminUserIds: koishi_1.Schema.array(String).default([]).description('管理员用户 ID 列表'),
|
|
102
101
|
autoRefreshEnabled: koishi_1.Schema.boolean().default(false).description('启用自动刷新凭证'),
|
|
@@ -1,60 +1,68 @@
|
|
|
1
|
-
<!DOCTYPE html>
|
|
2
|
-
<html lang="zh-CN">
|
|
3
|
-
<head>
|
|
4
|
-
<meta charset="utf-8">
|
|
5
|
-
<meta name="viewport" content="width=
|
|
6
|
-
<link rel="stylesheet" href="{{_res_path}}render/player-search/style.css">
|
|
7
|
-
</head>
|
|
8
|
-
<body>
|
|
9
|
-
<div class="player-search-page player-page">
|
|
10
|
-
<div class="page-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
<div class="
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
{{
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
{{
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
{{
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
</
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="zh-CN">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8">
|
|
5
|
+
<meta name="viewport" content="width=1280, initial-scale=1">
|
|
6
|
+
<link rel="stylesheet" href="{{_res_path}}render/player-search/style.css">
|
|
7
|
+
</head>
|
|
8
|
+
<body>
|
|
9
|
+
<div class="player-search-page player-page">
|
|
10
|
+
<div class="page-bg"></div>
|
|
11
|
+
|
|
12
|
+
<header class="page-header">
|
|
13
|
+
<div class="page-title">{{title}}</div>
|
|
14
|
+
<div class="page-title-ghost">ROCOM PLAYER</div>
|
|
15
|
+
</header>
|
|
16
|
+
|
|
17
|
+
<section class="profile-strip">
|
|
18
|
+
<div class="profile-main">
|
|
19
|
+
<div class="profile-name-row">
|
|
20
|
+
<span class="player-name">{{heroValue}}</span>
|
|
21
|
+
<span class="uid-pill">{{heroSubvalue}}</span>
|
|
22
|
+
</div>
|
|
23
|
+
</div>
|
|
24
|
+
</section>
|
|
25
|
+
|
|
26
|
+
<section class="summary-strip">
|
|
27
|
+
{{each summaryCards item}}
|
|
28
|
+
<div class="summary-item">
|
|
29
|
+
<div class="summary-label">{{item.label}}</div>
|
|
30
|
+
<div class="summary-value">{{item.value}}</div>
|
|
31
|
+
</div>
|
|
32
|
+
{{/each}}
|
|
33
|
+
</section>
|
|
34
|
+
|
|
35
|
+
{{if showSignature}}
|
|
36
|
+
<section class="signature-strip">
|
|
37
|
+
<div class="signature-label">个性签名</div>
|
|
38
|
+
<div class="signature-text">{{signature}}</div>
|
|
39
|
+
</section>
|
|
40
|
+
{{/if}}
|
|
41
|
+
|
|
42
|
+
<main class="content-grid">
|
|
43
|
+
{{each sections section}}
|
|
44
|
+
<section class="panel">
|
|
45
|
+
<div class="panel-head">
|
|
46
|
+
<h2>{{section.title}}</h2>
|
|
47
|
+
</div>
|
|
48
|
+
<div class="detail-list">
|
|
49
|
+
{{each section["items"] item}}
|
|
50
|
+
<div class="detail-row">
|
|
51
|
+
<span class="detail-label">{{item.label}}</span>
|
|
52
|
+
<span class="detail-value">{{item.value}}</span>
|
|
53
|
+
</div>
|
|
54
|
+
{{/each}}
|
|
55
|
+
</div>
|
|
56
|
+
</section>
|
|
57
|
+
{{/each}}
|
|
58
|
+
</main>
|
|
59
|
+
|
|
60
|
+
<footer class="page-footer">
|
|
61
|
+
{{if commandHint}}
|
|
62
|
+
<div class="command-hint">用法:{{commandHint}}</div>
|
|
63
|
+
{{/if}}
|
|
64
|
+
<div class="copyright">{{copyright}}</div>
|
|
65
|
+
</footer>
|
|
66
|
+
</div>
|
|
67
|
+
</body>
|
|
68
|
+
</html>
|