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 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
- this.setLastError(body.message || body.msg || '接口返回异常');
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/wiki/pet', this.wegameHeaders(), { q: query, limit });
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/wiki/skill', this.wegameHeaders(), { q: query, limit });
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;
@@ -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=1200, 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-header">
11
- <div class="page-title">{{title}}</div>
12
- <div class="page-subtitle">{{subtitle}}</div>
13
- </div>
14
-
15
- <div class="hero-card">
16
- <div class="hero-title">{{heroTitle}}</div>
17
- <div class="hero-value">{{heroValue}}</div>
18
- <div class="hero-subvalue">{{heroSubvalue}}</div>
19
- </div>
20
-
21
- <div class="summary-grid">
22
- {{each summaryCards item}}
23
- <div class="summary-card">
24
- <div class="summary-label">{{item.label}}</div>
25
- <div class="summary-value">{{item.value}}</div>
26
- </div>
27
- {{/each}}
28
- </div>
29
-
30
- {{if showSignature}}
31
- <div class="panel-card signature-panel">
32
- <div class="section-title">个性签名</div>
33
- <div class="signature-box">{{signature}}</div>
34
- </div>
35
- {{/if}}
36
-
37
- <div class="section-grid">
38
- {{each sections section}}
39
- <div class="panel-card info-panel">
40
- <div class="section-title">{{section.title}}</div>
41
- <div class="detail-card">
42
- {{each section["items"] item}}
43
- <div class="detail-row">
44
- <div class="detail-label">{{item.label}}</div>
45
- <div class="detail-value">{{item.value}}</div>
46
- </div>
47
- {{/each}}
48
- </div>
49
- </div>
50
- {{/each}}
51
- </div>
52
-
53
- {{if commandHint}}
54
- <div class="command-hint">{{commandHint}}</div>
55
- {{/if}}
56
-
57
- <div class="footer">{{copyright}}</div>
58
- </div>
59
- </body>
60
- </html>
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>