koishi-plugin-rocom 1.0.18 → 1.0.24
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/announcement-service.d.ts +21 -0
- package/lib/announcement-service.js +63 -0
- package/lib/async-control.d.ts +3 -0
- package/lib/async-control.js +48 -0
- package/lib/atlas-service.js +1 -1
- package/lib/client.d.ts +58 -7
- package/lib/client.js +282 -127
- package/lib/commands/egg.js +66 -4
- package/lib/commands/merchant.d.ts +105 -0
- package/lib/commands/merchant.js +600 -182
- package/lib/commands/query.d.ts +18 -0
- package/lib/commands/query.js +585 -145
- package/lib/commands/ranking.d.ts +2 -0
- package/lib/commands/ranking.js +31 -0
- package/lib/commands/share-code.d.ts +2 -0
- package/lib/commands/share-code.js +111 -0
- package/lib/commands/tools.js +48 -60
- package/lib/commands/wiki.js +1 -1
- package/lib/egg-service.d.ts +82 -8
- package/lib/egg-service.js +235 -19
- package/lib/element-colors.d.ts +3 -0
- package/lib/element-colors.js +34 -0
- package/lib/icon-metrics.d.ts +32 -0
- package/lib/icon-metrics.js +255 -0
- package/lib/img//345/274/202/350/211/262.png +0 -0
- package/lib/img//347/202/253/345/275/251.png +0 -0
- package/lib/index.d.ts +10 -0
- package/lib/index.js +11857 -175
- package/lib/merchant-catalog.d.ts +47 -0
- package/lib/merchant-catalog.js +193 -0
- package/lib/merchant-clock.d.ts +22 -0
- package/lib/merchant-clock.js +95 -0
- package/lib/merchant-price-log.d.ts +63 -0
- package/lib/merchant-price-log.js +187 -0
- package/lib/merchant-service.d.ts +38 -0
- package/lib/merchant-service.js +216 -0
- package/lib/permissions.d.ts +16 -0
- package/lib/permissions.js +66 -0
- package/lib/pet-data-service.d.ts +13 -0
- package/lib/pet-data-service.js +117 -10
- package/lib/pet-size.d.ts +13 -0
- package/lib/pet-size.js +54 -0
- package/lib/player-service.d.ts +37 -0
- package/lib/player-service.js +201 -0
- package/lib/ranking-service.d.ts +46 -0
- package/lib/ranking-service.js +137 -0
- package/lib/render-templates/announcement/detail.html +8 -0
- package/lib/render-templates/announcement/list.html +5 -0
- package/lib/render-templates/announcement/style.css +1 -0
- package/lib/render-templates/home/style.css +15 -14
- package/lib/render-templates/home-pets/index.html +80 -0
- package/lib/render-templates/home-pets/style.css +338 -0
- package/lib/render-templates/pet-detail-classic/index.html +151 -0
- package/lib/render-templates/pet-detail-classic/style.css +503 -0
- package/lib/render-templates/pet-detail-classic/texture2D/a_title.png +0 -0
- package/lib/render-templates/pet-detail-classic/texture2D/bg.jpg +0 -0
- package/lib/render-templates/pet-detail-classic/texture2D/footer.png +0 -0
- package/lib/render-templates/pet-detail-classic/texture2D/icon.png +0 -0
- package/lib/render-templates/pet-detail-classic/texture2D/img_head.png +0 -0
- package/lib/render-templates/pet-detail-classic/texture2D/jinhua_bg.png +0 -0
- package/lib/render-templates/pet-detail-classic/texture2D/level_icon.png +0 -0
- package/lib/render-templates/pet-detail-classic/texture2D/line.png +0 -0
- package/lib/render-templates/pet-detail-classic/texture2D/mask_bar.png +0 -0
- package/lib/render-templates/pet-detail-classic/texture2D/pet_bg.png +0 -0
- package/lib/render-templates/pet-detail-classic/texture2D/pet_rocom.png +0 -0
- package/lib/render-templates/pet-detail-classic/texture2D/pet_rocom_bg.png +0 -0
- package/lib/render-templates/pet-detail-classic/texture2D/poro_bar.png +0 -0
- package/lib/render-templates/pet-detail-classic/texture2D/right_jinhua.png +0 -0
- package/lib/render-templates/pet-detail-classic/texture2D/skill_bg.png +0 -0
- package/lib/render-templates/pet-detail-classic/texture2D/skill_mask.png +0 -0
- package/lib/render-templates/pet-detail-classic/texture2D/star.png +0 -0
- package/lib/render-templates/pet-detail-classic/texture2D/star_1.png +0 -0
- package/lib/render-templates/pet-detail-classic/texture2D/star_8.png +0 -0
- package/lib/render-templates/pet-detail-classic/texture2D/star_9.png +0 -0
- package/lib/render-templates/pet-detail-classic/texture2D/table.png +0 -0
- package/lib/render-templates/pet-detail-classic/texture2D/tags.png +0 -0
- package/lib/render-templates/pet-detail-classic/texture2D/title.png +0 -0
- package/lib/render-templates/pet-detail-classic/texture2D/top_bg.png +0 -0
- package/lib/render-templates/pet-detail-classic/texture2D/xuancai_overlay.png +0 -0
- package/lib/render-templates/pet-detail-classic/texture2D/yise_overlay.png +0 -0
- package/lib/render-templates/pet-detail-classic/texture2D/ys_bar.png +0 -0
- package/lib/render-templates/pet-detail-classic/texture2D//345/261/236/346/200/247/10.png +0 -0
- package/lib/render-templates/pet-detail-classic/texture2D//345/261/236/346/200/247/11.png +0 -0
- package/lib/render-templates/pet-detail-classic/texture2D//345/261/236/346/200/247/12.png +0 -0
- package/lib/render-templates/pet-detail-classic/texture2D//345/261/236/346/200/247/13.png +0 -0
- package/lib/render-templates/pet-detail-classic/texture2D//345/261/236/346/200/247/14.png +0 -0
- package/lib/render-templates/pet-detail-classic/texture2D//345/261/236/346/200/247/15.png +0 -0
- package/lib/render-templates/pet-detail-classic/texture2D//345/261/236/346/200/247/16.png +0 -0
- package/lib/render-templates/pet-detail-classic/texture2D//345/261/236/346/200/247/17.png +0 -0
- package/lib/render-templates/pet-detail-classic/texture2D//345/261/236/346/200/247/18.png +0 -0
- package/lib/render-templates/pet-detail-classic/texture2D//345/261/236/346/200/247/19.png +0 -0
- package/lib/render-templates/pet-detail-classic/texture2D//345/261/236/346/200/247/2.png +0 -0
- package/lib/render-templates/pet-detail-classic/texture2D//345/261/236/346/200/247/20.png +0 -0
- package/lib/render-templates/pet-detail-classic/texture2D//345/261/236/346/200/247/23.png +0 -0
- package/lib/render-templates/pet-detail-classic/texture2D//345/261/236/346/200/247/3.png +0 -0
- package/lib/render-templates/pet-detail-classic/texture2D//345/261/236/346/200/247/4.png +0 -0
- package/lib/render-templates/pet-detail-classic/texture2D//345/261/236/346/200/247/5.png +0 -0
- package/lib/render-templates/pet-detail-classic/texture2D//345/261/236/346/200/247/6.png +0 -0
- package/lib/render-templates/pet-detail-classic/texture2D//345/261/236/346/200/247/8.png +0 -0
- package/lib/render-templates/pet-detail-classic/texture2D//345/261/236/346/200/247/9.png +0 -0
- package/lib/render-templates/pet-detail-classic/texture2D//345/261/236/346/200/247//345/205/211.png +0 -0
- package/lib/render-templates/pet-detail-classic/texture2D//345/261/236/346/200/247//345/206/260.png +0 -0
- package/lib/render-templates/pet-detail-classic/texture2D//345/261/236/346/200/247//345/234/260.png +0 -0
- package/lib/render-templates/pet-detail-classic/texture2D//345/261/236/346/200/247//345/271/273.png +0 -0
- package/lib/render-templates/pet-detail-classic/texture2D//345/261/236/346/200/247//345/271/275.png +0 -0
- package/lib/render-templates/pet-detail-classic/texture2D//345/261/236/346/200/247//346/201/266.png +0 -0
- package/lib/render-templates/pet-detail-classic/texture2D//345/261/236/346/200/247//346/227/240.png +0 -0
- package/lib/render-templates/pet-detail-classic/texture2D//345/261/236/346/200/247//346/231/256/351/200/232.png +0 -0
- package/lib/render-templates/pet-detail-classic/texture2D//345/261/236/346/200/247//346/234/272/346/242/260.png +0 -0
- package/lib/render-templates/pet-detail-classic/texture2D//345/261/236/346/200/247//346/255/246.png +0 -0
- package/lib/render-templates/pet-detail-classic/texture2D//345/261/236/346/200/247//346/257/222.png +0 -0
- package/lib/render-templates/pet-detail-classic/texture2D//345/261/236/346/200/247//346/260/264.png +0 -0
- package/lib/render-templates/pet-detail-classic/texture2D//345/261/236/346/200/247//347/201/253.png +0 -0
- package/lib/render-templates/pet-detail-classic/texture2D//345/261/236/346/200/247//347/224/265.png +0 -0
- package/lib/render-templates/pet-detail-classic/texture2D//345/261/236/346/200/247//347/277/274.png +0 -0
- package/lib/render-templates/pet-detail-classic/texture2D//345/261/236/346/200/247//350/215/211.png +0 -0
- package/lib/render-templates/pet-detail-classic/texture2D//345/261/236/346/200/247//350/220/214.png +0 -0
- package/lib/render-templates/pet-detail-classic/texture2D//345/261/236/346/200/247//350/231/253.png +0 -0
- package/lib/render-templates/pet-detail-classic/texture2D//345/261/236/346/200/247//351/276/231.png +0 -0
- package/lib/render-templates/pet-detail-classic/texture2D//350/241/200/350/204/211/1.png +0 -0
- package/lib/render-templates/pet-detail-classic/texture2D//350/241/200/350/204/211/10.png +0 -0
- package/lib/render-templates/pet-detail-classic/texture2D//350/241/200/350/204/211/11.png +0 -0
- package/lib/render-templates/pet-detail-classic/texture2D//350/241/200/350/204/211/12.png +0 -0
- package/lib/render-templates/pet-detail-classic/texture2D//350/241/200/350/204/211/13.png +0 -0
- package/lib/render-templates/pet-detail-classic/texture2D//350/241/200/350/204/211/14.png +0 -0
- package/lib/render-templates/pet-detail-classic/texture2D//350/241/200/350/204/211/15.png +0 -0
- package/lib/render-templates/pet-detail-classic/texture2D//350/241/200/350/204/211/16.png +0 -0
- package/lib/render-templates/pet-detail-classic/texture2D//350/241/200/350/204/211/17.png +0 -0
- package/lib/render-templates/pet-detail-classic/texture2D//350/241/200/350/204/211/18.png +0 -0
- package/lib/render-templates/pet-detail-classic/texture2D//350/241/200/350/204/211/19.png +0 -0
- package/lib/render-templates/pet-detail-classic/texture2D//350/241/200/350/204/211/2.png +0 -0
- package/lib/render-templates/pet-detail-classic/texture2D//350/241/200/350/204/211/21.png +0 -0
- package/lib/render-templates/pet-detail-classic/texture2D//350/241/200/350/204/211/23.png +0 -0
- package/lib/render-templates/pet-detail-classic/texture2D//350/241/200/350/204/211/24.png +0 -0
- package/lib/render-templates/pet-detail-classic/texture2D//350/241/200/350/204/211/3.png +0 -0
- package/lib/render-templates/pet-detail-classic/texture2D//350/241/200/350/204/211/4.png +0 -0
- package/lib/render-templates/pet-detail-classic/texture2D//350/241/200/350/204/211/5.png +0 -0
- package/lib/render-templates/pet-detail-classic/texture2D//350/241/200/350/204/211/6.png +0 -0
- package/lib/render-templates/pet-detail-classic/texture2D//350/241/200/350/204/211/7.png +0 -0
- package/lib/render-templates/pet-detail-classic/texture2D//350/241/200/350/204/211/8.png +0 -0
- package/lib/render-templates/pet-detail-classic/texture2D//350/241/200/350/204/211/9.png +0 -0
- package/lib/render-templates/pet-ranking/index.html +99 -0
- package/lib/render-templates/pet-ranking/style.css +338 -0
- package/lib/render-templates/player-search/index.html +7 -0
- package/lib/render-templates/searcheggs/index.html +1 -1
- package/lib/render-templates/searcheggs/size.html +70 -68
- package/lib/render-templates/share-code-classic/assets/eit-logo.png +0 -0
- package/lib/render-templates/share-code-classic/assets/img_xingxingdi.png +0 -0
- package/lib/render-templates/share-code-classic/assets/roco_icon.png +0 -0
- package/lib/render-templates/share-code-classic/assets//345/255/227/344/275/223/Rocofontblack-Regular .ttf +0 -0
- package/lib/render-templates/share-code-classic/assets//345/256/240/347/211/251/345/261/236/346/200/247//345/205/211.png +0 -0
- package/lib/render-templates/share-code-classic/assets//345/256/240/347/211/251/345/261/236/346/200/247//345/206/260.png +0 -0
- package/lib/render-templates/share-code-classic/assets//345/256/240/347/211/251/345/261/236/346/200/247//345/234/260.png +0 -0
- package/lib/render-templates/share-code-classic/assets//345/256/240/347/211/251/345/261/236/346/200/247//345/271/273.png +0 -0
- package/lib/render-templates/share-code-classic/assets//345/256/240/347/211/251/345/261/236/346/200/247//345/271/275.png +0 -0
- package/lib/render-templates/share-code-classic/assets//345/256/240/347/211/251/345/261/236/346/200/247//346/201/266.png +0 -0
- package/lib/render-templates/share-code-classic/assets//345/256/240/347/211/251/345/261/236/346/200/247//346/227/240.png +0 -0
- package/lib/render-templates/share-code-classic/assets//345/256/240/347/211/251/345/261/236/346/200/247//346/231/256/351/200/232.png +0 -0
- package/lib/render-templates/share-code-classic/assets//345/256/240/347/211/251/345/261/236/346/200/247//346/234/272/346/242/260.png +0 -0
- package/lib/render-templates/share-code-classic/assets//345/256/240/347/211/251/345/261/236/346/200/247//346/255/246.png +0 -0
- package/lib/render-templates/share-code-classic/assets//345/256/240/347/211/251/345/261/236/346/200/247//346/257/222.png +0 -0
- package/lib/render-templates/share-code-classic/assets//345/256/240/347/211/251/345/261/236/346/200/247//346/260/264.png +0 -0
- package/lib/render-templates/share-code-classic/assets//345/256/240/347/211/251/345/261/236/346/200/247//347/201/253.png +0 -0
- package/lib/render-templates/share-code-classic/assets//345/256/240/347/211/251/345/261/236/346/200/247//347/224/265.png +0 -0
- package/lib/render-templates/share-code-classic/assets//345/256/240/347/211/251/345/261/236/346/200/247//347/277/274.png +0 -0
- package/lib/render-templates/share-code-classic/assets//345/256/240/347/211/251/345/261/236/346/200/247//350/215/211.png +0 -0
- package/lib/render-templates/share-code-classic/assets//345/256/240/347/211/251/345/261/236/346/200/247//350/220/214.png +0 -0
- package/lib/render-templates/share-code-classic/assets//345/256/240/347/211/251/345/261/236/346/200/247//350/231/253.png +0 -0
- package/lib/render-templates/share-code-classic/assets//345/256/240/347/211/251/345/261/236/346/200/247//351/276/231.png +0 -0
- package/lib/render-templates/share-code-classic/assets//347/201/253/346/274/206/345/215/260.png +0 -0
- package/lib/render-templates/share-code-classic/assets//347/253/213/347/273/230/350/203/214/346/231/257/346/241/206.png +0 -0
- package/lib/render-templates/share-code-classic/assets//350/241/200/350/204/211//345/205/211.png +0 -0
- package/lib/render-templates/share-code-classic/assets//350/241/200/350/204/211//345/206/260.png +0 -0
- package/lib/render-templates/share-code-classic/assets//350/241/200/350/204/211//345/234/260.png +0 -0
- package/lib/render-templates/share-code-classic/assets//350/241/200/350/204/211//345/245/207/345/274/202.png +0 -0
- package/lib/render-templates/share-code-classic/assets//350/241/200/350/204/211//345/271/273.png +0 -0
- package/lib/render-templates/share-code-classic/assets//350/241/200/350/204/211//345/271/275.png +0 -0
- package/lib/render-templates/share-code-classic/assets//350/241/200/350/204/211//346/201/266.png +0 -0
- package/lib/render-templates/share-code-classic/assets//350/241/200/350/204/211//346/231/256/351/200/232.png +0 -0
- package/lib/render-templates/share-code-classic/assets//350/241/200/350/204/211//346/234/272/346/242/260.png +0 -0
- package/lib/render-templates/share-code-classic/assets//350/241/200/350/204/211//346/255/246.png +0 -0
- package/lib/render-templates/share-code-classic/assets//350/241/200/350/204/211//346/257/222.png +0 -0
- package/lib/render-templates/share-code-classic/assets//350/241/200/350/204/211//346/260/264.png +0 -0
- package/lib/render-templates/share-code-classic/assets//350/241/200/350/204/211//346/261/241/346/237/223.png +0 -0
- package/lib/render-templates/share-code-classic/assets//350/241/200/350/204/211//347/201/253.png +0 -0
- package/lib/render-templates/share-code-classic/assets//350/241/200/350/204/211//347/224/265.png +0 -0
- package/lib/render-templates/share-code-classic/assets//350/241/200/350/204/211//347/277/274.png +0 -0
- package/lib/render-templates/share-code-classic/assets//350/241/200/350/204/211//350/215/211.png +0 -0
- package/lib/render-templates/share-code-classic/assets//350/241/200/350/204/211//350/220/214.png +0 -0
- package/lib/render-templates/share-code-classic/assets//350/241/200/350/204/211//350/231/253.png +0 -0
- package/lib/render-templates/share-code-classic/assets//350/241/200/350/204/211//351/246/226/351/242/206.png +0 -0
- package/lib/render-templates/share-code-classic/assets//350/241/200/350/204/211//351/276/231.png +0 -0
- package/lib/render-templates/share-code-classic/index.html +119 -0
- package/lib/render-templates/share-code-classic/style.css +646 -0
- package/lib/render-templates/share-code-team/index.html +105 -0
- package/lib/render-templates/share-code-team/style.css +345 -0
- package/lib/render-templates/yuanxing-shangren/merchant.html +479 -461
- package/lib/render-templates/yuanxing-shangren/today.html +407 -461
- package/lib/render.d.ts +18 -2
- package/lib/render.js +138 -39
- package/lib/send-image.d.ts +1 -1
- package/lib/send-image.js +22 -1
- package/lib/share-code-service.d.ts +68 -0
- package/lib/share-code-service.js +257 -0
- package/lib/subscription-runner.d.ts +6 -0
- package/lib/subscription-runner.js +21 -0
- package/lib/subscription-send.d.ts +4 -2
- package/lib/subscription-send.js +45 -20
- package/lib/ttf/rocom_origin.ttf +0 -0
- package/lib/types.d.ts +14 -1
- package/lib/user.d.ts +11 -0
- package/lib/wiki-catalog.js +1 -1
- package/lib/wiki-service.js +1 -1
- package/package.json +5 -1
- package/readme.md +125 -124
- package/lib/ttf/rocom_skill_origin.ttf +0 -0
package/lib/client.js
CHANGED
|
@@ -1,12 +1,22 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.RocomClient = void 0;
|
|
3
|
+
exports.RocomClient = exports.isObject = void 0;
|
|
4
|
+
exports.inheritGoodsMapping = inheritGoodsMapping;
|
|
4
5
|
const koishi_1 = require("koishi");
|
|
6
|
+
const async_control_1 = require("./async-control");
|
|
5
7
|
const logger = new koishi_1.Logger('rocom-client');
|
|
6
8
|
// ingame 异步任务状态分类(来自服务端 /ingame/tasks/{task_id} 返回的 status 字段)
|
|
7
9
|
const INGAME_PENDING_STATUSES = ['queued', 'pending', 'running', 'processing', 'accepted'];
|
|
8
10
|
const INGAME_FAILED_STATUSES = ['failed', 'error', 'timeout', 'cancelled', 'canceled'];
|
|
9
11
|
const INGAME_COMPLETED_STATUSES = ['done', 'success', 'succeeded', 'completed', 'finished'];
|
|
12
|
+
const isObject = (v) => v !== null && typeof v === 'object' && !Array.isArray(v);
|
|
13
|
+
exports.isObject = isObject;
|
|
14
|
+
// 每剥离一层 envelope 时继承 goods_mapping,避免只改商品渲染后拿不到名称/图标。
|
|
15
|
+
function inheritGoodsMapping(parent, child) {
|
|
16
|
+
const mapping = child._goods_mapping ?? child.goods_mapping
|
|
17
|
+
?? parent._goods_mapping ?? parent.goods_mapping;
|
|
18
|
+
return mapping === undefined ? { ...child } : { ...child, _goods_mapping: mapping };
|
|
19
|
+
}
|
|
10
20
|
class RocomClient {
|
|
11
21
|
baseUrl;
|
|
12
22
|
apiKey;
|
|
@@ -23,6 +33,12 @@ class RocomClient {
|
|
|
23
33
|
return '';
|
|
24
34
|
return uid.trim().replace(/[^a-zA-Z0-9_\- \u4e00-\u9fa5]/g, '').trim();
|
|
25
35
|
}
|
|
36
|
+
// HTTP/任务 envelope 的 goods_mapping 复制到业务对象,供商品名称与图标解析。
|
|
37
|
+
attachGoodsMapping(resp, data) {
|
|
38
|
+
if ((0, exports.isObject)(resp) && (0, exports.isObject)(data))
|
|
39
|
+
return inheritGoodsMapping(resp, data);
|
|
40
|
+
return data;
|
|
41
|
+
}
|
|
26
42
|
wegameHeaders(fwToken = '', userIdentifier = '', clientType = '', clientId = '', includeApiKey = true) {
|
|
27
43
|
const headers = {};
|
|
28
44
|
if (includeApiKey && this.apiKey)
|
|
@@ -192,6 +208,7 @@ class RocomClient {
|
|
|
192
208
|
headers,
|
|
193
209
|
params,
|
|
194
210
|
timeout: this.timeout,
|
|
211
|
+
signal: options?.signal,
|
|
195
212
|
});
|
|
196
213
|
if (resp?.code !== 0) {
|
|
197
214
|
this.setLastError(resp?.message || '接口返回异常');
|
|
@@ -201,7 +218,7 @@ class RocomClient {
|
|
|
201
218
|
}
|
|
202
219
|
return null;
|
|
203
220
|
}
|
|
204
|
-
return resp?.data ?? {};
|
|
221
|
+
return this.attachGoodsMapping(resp, resp?.data ?? {});
|
|
205
222
|
}
|
|
206
223
|
catch (e) {
|
|
207
224
|
const message = this.formatHttpError(e);
|
|
@@ -219,12 +236,13 @@ class RocomClient {
|
|
|
219
236
|
return null;
|
|
220
237
|
}
|
|
221
238
|
}
|
|
222
|
-
async post(ctx, path, headers, json, params) {
|
|
239
|
+
async post(ctx, path, headers, json, params, signal) {
|
|
223
240
|
try {
|
|
224
241
|
const resp = await ctx.http.post(`${this.baseUrl}${path}`, json, {
|
|
225
242
|
headers,
|
|
226
243
|
params,
|
|
227
244
|
timeout: this.timeout,
|
|
245
|
+
signal,
|
|
228
246
|
});
|
|
229
247
|
if (resp?.code !== 0) {
|
|
230
248
|
this.setLastError(resp?.message || '接口返回异常');
|
|
@@ -232,7 +250,7 @@ class RocomClient {
|
|
|
232
250
|
this.logRequestFailureDetails('POST', path, headers, params, json, resp);
|
|
233
251
|
return null;
|
|
234
252
|
}
|
|
235
|
-
return resp?.data ?? {};
|
|
253
|
+
return this.attachGoodsMapping(resp, resp?.data ?? {});
|
|
236
254
|
}
|
|
237
255
|
catch (e) {
|
|
238
256
|
const message = this.formatHttpError(e);
|
|
@@ -263,7 +281,7 @@ class RocomClient {
|
|
|
263
281
|
this.logRequestFailureDetails('DELETE', path, headers, params, undefined, resp);
|
|
264
282
|
return null;
|
|
265
283
|
}
|
|
266
|
-
return resp?.data ?? {};
|
|
284
|
+
return this.attachGoodsMapping(resp, resp?.data ?? {});
|
|
267
285
|
}
|
|
268
286
|
catch (e) {
|
|
269
287
|
const message = this.formatHttpError(e);
|
|
@@ -287,14 +305,16 @@ class RocomClient {
|
|
|
287
305
|
headers,
|
|
288
306
|
params: options.params,
|
|
289
307
|
data: options.json,
|
|
290
|
-
timeout: this.timeout,
|
|
308
|
+
timeout: Math.max(this.timeout, Number(options.json?.wait_ms ?? options.params?.wait_ms ?? 0) + 2000),
|
|
309
|
+
signal: options.signal,
|
|
291
310
|
validateStatus: () => true,
|
|
292
311
|
});
|
|
293
|
-
const
|
|
312
|
+
const rawStatus = Number(response?.status);
|
|
313
|
+
const status = Number.isFinite(rawStatus) ? rawStatus : null;
|
|
294
314
|
const body = response?.data !== undefined ? response.data : response;
|
|
295
315
|
if (body?.code !== undefined && body.code !== 0) {
|
|
296
316
|
const rawMessage = body.message || body.msg || '接口返回异常';
|
|
297
|
-
const message = !acceptedStatuses.includes(status)
|
|
317
|
+
const message = status !== null && !acceptedStatuses.includes(status)
|
|
298
318
|
? `HTTP ${status}: ${rawMessage}`
|
|
299
319
|
: rawMessage;
|
|
300
320
|
this.setLastError(message);
|
|
@@ -303,9 +323,9 @@ class RocomClient {
|
|
|
303
323
|
}
|
|
304
324
|
return { status: null, data: null };
|
|
305
325
|
}
|
|
306
|
-
const data = body?.code !== undefined ? (body.data ?? {}) : (body ?? {});
|
|
307
|
-
if (!acceptedStatuses.includes(status)) {
|
|
308
|
-
this.setLastError(`HTTP ${status}`);
|
|
326
|
+
const data = body?.code !== undefined ? this.attachGoodsMapping(body, body.data ?? {}) : (body ?? {});
|
|
327
|
+
if (status === null || !acceptedStatuses.includes(status)) {
|
|
328
|
+
this.setLastError(status === null ? 'HTTP 响应缺少状态码' : `HTTP ${status}`);
|
|
309
329
|
if (!options.silentFailureDetails) {
|
|
310
330
|
this.logRequestFailureDetails(method, path, headers, options.params, options.json, response);
|
|
311
331
|
}
|
|
@@ -324,18 +344,21 @@ class RocomClient {
|
|
|
324
344
|
}
|
|
325
345
|
async requestIngameWithFallback(ctx, path, payload, options = {}) {
|
|
326
346
|
const acceptedStatuses = options.acceptedStatuses || [200, 202];
|
|
347
|
+
const auth = options.auth || {};
|
|
327
348
|
const requestOnce = async (includeApiKey, silentFailureDetails) => {
|
|
328
|
-
const headers = this.wegameHeaders('', '', '', '', includeApiKey);
|
|
349
|
+
const headers = this.wegameHeaders(auth.fwToken || '', auth.userIdentifier || '', '', '', includeApiKey);
|
|
329
350
|
let result = await this.requestWithStatus(ctx, 'POST', path, headers, {
|
|
330
351
|
json: payload,
|
|
331
352
|
acceptedStatuses,
|
|
332
353
|
silentFailureDetails,
|
|
354
|
+
signal: options.signal,
|
|
333
355
|
});
|
|
334
|
-
if (result.status === null) {
|
|
356
|
+
if (result.status === null && !options.signal?.aborted) {
|
|
335
357
|
result = await this.requestWithStatus(ctx, 'GET', path, headers, {
|
|
336
358
|
params: payload,
|
|
337
359
|
acceptedStatuses,
|
|
338
360
|
silentFailureDetails,
|
|
361
|
+
signal: options.signal,
|
|
339
362
|
});
|
|
340
363
|
}
|
|
341
364
|
return result;
|
|
@@ -343,15 +366,15 @@ class RocomClient {
|
|
|
343
366
|
let result = await requestOnce(false, Boolean(this.apiKey));
|
|
344
367
|
if (result.status !== null)
|
|
345
368
|
return { ...result, usedApiKey: false };
|
|
346
|
-
if (this.shouldRetryIngameWithApiKey(this.getLastError())) {
|
|
369
|
+
if (!options.signal?.aborted && this.shouldRetryIngameWithApiKey(this.getLastError())) {
|
|
347
370
|
result = await requestOnce(true, false);
|
|
348
371
|
if (result.status !== null)
|
|
349
372
|
return { ...result, usedApiKey: true };
|
|
350
373
|
}
|
|
351
374
|
return { status: null, data: null, usedApiKey: false };
|
|
352
375
|
}
|
|
353
|
-
async getIngameTask(ctx, taskId, includeApiKey = true) {
|
|
354
|
-
return this.requestWithStatus(ctx, 'GET', `/api/v1/games/rocom/ingame/tasks/${taskId}`, this.wegameHeaders('', '', '', '', includeApiKey), { acceptedStatuses: [200, 202] });
|
|
376
|
+
async getIngameTask(ctx, taskId, includeApiKey = true, auth = {}, signal) {
|
|
377
|
+
return this.requestWithStatus(ctx, 'GET', `/api/v1/games/rocom/ingame/tasks/${taskId}`, this.wegameHeaders(auth.fwToken || '', auth.userIdentifier || '', '', '', includeApiKey), { acceptedStatuses: [200, 202], signal });
|
|
355
378
|
}
|
|
356
379
|
static normalizeTaskStatus(value) {
|
|
357
380
|
return String(value ?? '').trim().toLowerCase();
|
|
@@ -361,7 +384,8 @@ class RocomClient {
|
|
|
361
384
|
}
|
|
362
385
|
// 判断一份 payload 是否为“已完成的业务结果”(而非排队占位)。
|
|
363
386
|
// 家园接口完成时返回 rows/home_info;玩家、商店完成时返回 source/title/rows;
|
|
364
|
-
// 家园详情(pet/data)完成时返回 npc_pets/npc_pet
|
|
387
|
+
// 家园详情(pet/data)完成时返回 npc_pets/npc_pet;
|
|
388
|
+
// v4.1 玩家嵌套结构返回 player_info/player_card_brief_info,实时商人返回 goods/shop/meta。
|
|
365
389
|
static isCompletedGatewayPayload(payload) {
|
|
366
390
|
if (!payload || typeof payload !== 'object')
|
|
367
391
|
return false;
|
|
@@ -369,26 +393,46 @@ class RocomClient {
|
|
|
369
393
|
return true;
|
|
370
394
|
if (payload.home_info !== undefined)
|
|
371
395
|
return true;
|
|
372
|
-
if (payload.source !== undefined)
|
|
373
|
-
return true;
|
|
374
396
|
if (Array.isArray(payload.npc_pets))
|
|
375
397
|
return true;
|
|
376
398
|
if (payload.npc_pet && typeof payload.npc_pet === 'object')
|
|
377
399
|
return true;
|
|
378
|
-
if (
|
|
400
|
+
if (payload.player_info && typeof payload.player_info === 'object')
|
|
401
|
+
return true;
|
|
402
|
+
if (payload.player_card_brief_info && typeof payload.player_card_brief_info === 'object')
|
|
403
|
+
return true;
|
|
404
|
+
if (Array.isArray(payload.goods))
|
|
405
|
+
return true;
|
|
406
|
+
if (payload.shop && typeof payload.shop === 'object')
|
|
407
|
+
return true;
|
|
408
|
+
if (payload.meta && typeof payload.meta === 'object' && Array.isArray(payload.goods))
|
|
379
409
|
return true;
|
|
380
410
|
return false;
|
|
381
411
|
}
|
|
382
|
-
static
|
|
383
|
-
if (!payload ||
|
|
384
|
-
return
|
|
412
|
+
static inspectIngamePayload(payload, depth = 0, completed = false) {
|
|
413
|
+
if (!(0, exports.isObject)(payload) || depth > 6)
|
|
414
|
+
return { error: '任务返回结构无法解析' };
|
|
415
|
+
const state = RocomClient.normalizeTaskStatus(payload.status);
|
|
416
|
+
if (INGAME_FAILED_STATUSES.includes(state))
|
|
417
|
+
return { error: RocomClient.taskErrorMessage(payload, state) };
|
|
418
|
+
if (INGAME_PENDING_STATUSES.includes(state))
|
|
419
|
+
return { pending: true };
|
|
420
|
+
if (state && !INGAME_COMPLETED_STATUSES.includes(state))
|
|
421
|
+
return { error: 'Ingame 任务状态异常:' + state };
|
|
422
|
+
completed ||= INGAME_COMPLETED_STATUSES.includes(state);
|
|
385
423
|
if (RocomClient.isCompletedGatewayPayload(payload))
|
|
386
|
-
return payload;
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
424
|
+
return { value: payload };
|
|
425
|
+
for (const key of ['result', 'data']) {
|
|
426
|
+
if ((0, exports.isObject)(payload[key]))
|
|
427
|
+
return RocomClient.inspectIngamePayload(inheritGoodsMapping(payload, payload[key]), depth + 1, completed);
|
|
428
|
+
}
|
|
429
|
+
if (completed)
|
|
430
|
+
return { error: '任务已完成但未返回可解析结果' };
|
|
431
|
+
if (state)
|
|
432
|
+
return { error: 'Ingame 任务状态异常:' + state };
|
|
433
|
+
if (RocomClient.extractTaskId(payload))
|
|
434
|
+
return { pending: true };
|
|
435
|
+
return { value: payload };
|
|
392
436
|
}
|
|
393
437
|
static taskErrorMessage(payload, fallbackStatus = '') {
|
|
394
438
|
const candidates = [
|
|
@@ -405,64 +449,65 @@ class RocomClient {
|
|
|
405
449
|
}
|
|
406
450
|
// 排队等候轮询:把 ingame 接口提交后返回的 202(task_id/status=queued)轮询到出结果或超时。
|
|
407
451
|
// 入参 first 是首请求拿到的 { status, data, usedApiKey }。
|
|
408
|
-
async pollIngameTask(ctx, first, options, labels) {
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
const
|
|
412
|
-
if (
|
|
413
|
-
|
|
414
|
-
|
|
452
|
+
async pollIngameTask(ctx, first, options, labels, auth = {}) {
|
|
453
|
+
if (first.status === null || options.signal?.aborted)
|
|
454
|
+
return null;
|
|
455
|
+
const initial = RocomClient.inspectIngamePayload(first.data);
|
|
456
|
+
if (initial.error) {
|
|
457
|
+
this.setLastError(initial.error);
|
|
458
|
+
return null;
|
|
459
|
+
}
|
|
460
|
+
const taskId = RocomClient.extractTaskId(first.data);
|
|
461
|
+
if (!initial.pending && initial.value !== undefined && first.status !== 202)
|
|
462
|
+
return initial.value;
|
|
415
463
|
if (!taskId) {
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
// 既不是任务也不是已知完成结构:把原始 data 透传给上层兼容旧逻辑。
|
|
419
|
-
return status === null ? null : data;
|
|
420
|
-
}
|
|
421
|
-
// 已进入队列,回调通知“排队中”。
|
|
422
|
-
if (typeof options.onQueued === 'function') {
|
|
423
|
-
try {
|
|
424
|
-
await options.onQueued(taskId);
|
|
425
|
-
}
|
|
426
|
-
catch (e) {
|
|
427
|
-
logger.warn(`ingame 排队提示回调失败: ${e}`);
|
|
428
|
-
}
|
|
464
|
+
this.setLastError(labels.queuedNoTaskId);
|
|
465
|
+
return null;
|
|
429
466
|
}
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
return null;
|
|
455
|
-
}
|
|
456
|
-
if (lastStatus && !INGAME_PENDING_STATUSES.includes(lastStatus)) {
|
|
457
|
-
this.setLastError(`Ingame 任务状态异常:${lastStatus}`);
|
|
467
|
+
try {
|
|
468
|
+
return await (0, async_control_1.withDeadline)(Math.max(1, Number(options.timeoutMs) || 180000), options.signal, async (signal) => {
|
|
469
|
+
if (options.onQueued) {
|
|
470
|
+
try {
|
|
471
|
+
await options.onQueued(taskId);
|
|
472
|
+
}
|
|
473
|
+
catch (error) {
|
|
474
|
+
logger.warn('排队提示失败: ' + error);
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
while (!signal.aborted) {
|
|
478
|
+
await (0, async_control_1.delay)(Math.max(300, Number(options.intervalMs) || 3000), signal);
|
|
479
|
+
const task = await this.getIngameTask(ctx, taskId, first.usedApiKey, auth, signal);
|
|
480
|
+
signal.throwIfAborted();
|
|
481
|
+
if (task.status === null)
|
|
482
|
+
return null;
|
|
483
|
+
const result = RocomClient.inspectIngamePayload(task.data);
|
|
484
|
+
if (result.error) {
|
|
485
|
+
this.setLastError(result.error);
|
|
486
|
+
return null;
|
|
487
|
+
}
|
|
488
|
+
if (!result.pending && result.value !== undefined && task.status !== 202)
|
|
489
|
+
return result.value;
|
|
490
|
+
}
|
|
458
491
|
return null;
|
|
459
|
-
}
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
492
|
+
});
|
|
493
|
+
}
|
|
494
|
+
catch {
|
|
495
|
+
this.setLastError(options.signal?.aborted ? '查询已取消' : labels.stillQueued(taskId));
|
|
496
|
+
return null;
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
async queuedQuery(ctx, path, payload, options, labels) {
|
|
500
|
+
try {
|
|
501
|
+
return await (0, async_control_1.withDeadline)(Number(options.timeoutMs) || 180000, options.signal, async (signal) => {
|
|
502
|
+
const first = await this.requestIngameWithFallback(ctx, path, payload, { auth: options.auth, signal });
|
|
503
|
+
signal.throwIfAborted();
|
|
504
|
+
return this.pollIngameTask(ctx, first, { ...options, signal }, labels, options.auth);
|
|
505
|
+
});
|
|
506
|
+
}
|
|
507
|
+
catch {
|
|
508
|
+
this.setLastError(options.signal?.aborted ? '查询已取消' : '查询等待超时,请稍后重试');
|
|
509
|
+
return null;
|
|
463
510
|
}
|
|
464
|
-
this.setLastError(labels.stillQueued(taskId));
|
|
465
|
-
return null;
|
|
466
511
|
}
|
|
467
512
|
async qqQrLogin(ctx, userIdentifier) {
|
|
468
513
|
const params = { client_type: 'bot', client_id: 'koishi', provider: 'rocom' };
|
|
@@ -562,39 +607,40 @@ class RocomClient {
|
|
|
562
607
|
|| Array.isArray(data.notes)
|
|
563
608
|
|| data.title
|
|
564
609
|
|| data.nickname
|
|
565
|
-
|| data.uid
|
|
610
|
+
|| data.uid
|
|
611
|
+
|| (data.player_info && typeof data.player_info === 'object')
|
|
612
|
+
|| (data.player_card_brief_info && typeof data.player_card_brief_info === 'object'));
|
|
566
613
|
}
|
|
567
|
-
async ingamePlayerSearch(ctx, uid) {
|
|
614
|
+
async ingamePlayerSearch(ctx, uid, options = {}) {
|
|
568
615
|
const sanitizedUid = this.sanitizeUid(uid);
|
|
569
|
-
if (!sanitizedUid) {
|
|
616
|
+
if (!sanitizedUid && !options.auth?.fwToken) {
|
|
570
617
|
this.setLastError('UID 不能为空');
|
|
571
618
|
return null;
|
|
572
619
|
}
|
|
573
620
|
const path = '/api/v1/games/rocom/ingame/player/search';
|
|
574
|
-
const payload = { uid: sanitizedUid, wait_ms: 5000 };
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
621
|
+
const payload = { ...(sanitizedUid ? { uid: sanitizedUid } : {}), wait_ms: Number(options.waitMs) || 5000 };
|
|
622
|
+
return this.queuedQuery(ctx, path, payload, options, {
|
|
623
|
+
queuedNoTaskId: '玩家搜索任务已入队,但未返回 task_id',
|
|
624
|
+
stillQueued: (taskId) => `玩家搜索任务仍在排队,请稍后重试(task_id: ${taskId})`,
|
|
625
|
+
});
|
|
626
|
+
}
|
|
627
|
+
// 玩家名片:需要补充收集数/名片图时按需查询。
|
|
628
|
+
async ingamePlayerCard(ctx, uid, options = {}) {
|
|
629
|
+
const sanitizedUid = this.sanitizeUid(uid);
|
|
630
|
+
if (!sanitizedUid && !options.auth?.fwToken) {
|
|
631
|
+
this.setLastError('UID 不能为空');
|
|
579
632
|
return null;
|
|
580
|
-
if (this.isIngamePlayerPayload(data))
|
|
581
|
-
return data;
|
|
582
|
-
const taskId = data.task_id || data.taskId || data.taskID;
|
|
583
|
-
if (!taskId) {
|
|
584
|
-
if (status === 202)
|
|
585
|
-
this.setLastError('玩家搜索任务已入队,但未返回 task_id');
|
|
586
|
-
return data;
|
|
587
|
-
}
|
|
588
|
-
for (let i = 0; i < 8; i++) {
|
|
589
|
-
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
590
|
-
const task = await this.getIngameTask(ctx, taskId, usedApiKey);
|
|
591
|
-
if (task.status === 200)
|
|
592
|
-
return task.data;
|
|
593
|
-
if (task.status === null)
|
|
594
|
-
return null;
|
|
595
633
|
}
|
|
596
|
-
|
|
597
|
-
|
|
634
|
+
const path = '/api/v1/games/rocom/ingame/player/card';
|
|
635
|
+
const payload = {
|
|
636
|
+
...(sanitizedUid ? { uid: sanitizedUid } : {}),
|
|
637
|
+
wait_ms: Number(options.waitMs) || 5000,
|
|
638
|
+
source: options.source || 'friend',
|
|
639
|
+
};
|
|
640
|
+
return this.queuedQuery(ctx, path, payload, options, {
|
|
641
|
+
queuedNoTaskId: '玩家名片任务已入队,但未返回 task_id',
|
|
642
|
+
stillQueued: (taskId) => `玩家名片任务仍在排队,请稍后重试(task_id: ${taskId})`,
|
|
643
|
+
});
|
|
598
644
|
}
|
|
599
645
|
async getPets(ctx, fwToken, petSubset = 0, pageNo = 1, pageSize = 10, userIdentifier = '') {
|
|
600
646
|
const params = { pet_subset: petSubset, page_no: pageNo, page_size: pageSize };
|
|
@@ -610,11 +656,30 @@ class RocomClient {
|
|
|
610
656
|
const params = { page_no: Math.max(pageNo, 1), refresh: 'false' };
|
|
611
657
|
return this.get(ctx, '/api/v1/games/rocom/exchange/posters', this.wegameHeaders(fwToken, userIdentifier), params);
|
|
612
658
|
}
|
|
613
|
-
|
|
614
|
-
|
|
659
|
+
// 远行商人:优先实时 ingame 接口,失败/协议无法识别时回退旧 merchant/info。
|
|
660
|
+
// 成功的空商品列表(goods: [])视为有效结果,不触发回退。
|
|
661
|
+
async getMerchantInfo(ctx, refresh = false, options = {}) {
|
|
662
|
+
const live = await this.ingameMerchantInfo(ctx, null, options);
|
|
663
|
+
if (live && typeof live === 'object' && (Array.isArray(live.goods)
|
|
664
|
+
|| Array.isArray(live.merchantActivities)
|
|
665
|
+
|| Array.isArray(live.merchant_activities))) {
|
|
666
|
+
return { ...live, _source: 'live' };
|
|
667
|
+
}
|
|
668
|
+
if (options.signal?.aborted)
|
|
669
|
+
return null;
|
|
670
|
+
return this.getLegacyMerchantInfo(ctx, refresh, options);
|
|
671
|
+
}
|
|
672
|
+
// 旧版 merchant/info 直取(商品目录 / 实时接口不可用时的回退)。
|
|
673
|
+
async getLegacyMerchantInfo(ctx, refresh = false, options = {}) {
|
|
674
|
+
const legacy = await this.get(ctx, '/api/v1/games/rocom/merchant/info', this.wegameHeaders(options.auth?.fwToken, options.auth?.userIdentifier), {
|
|
615
675
|
refresh: refresh ? 'true' : 'false',
|
|
616
676
|
random_goods: 'all',
|
|
617
|
-
});
|
|
677
|
+
}, { signal: options.signal });
|
|
678
|
+
if (legacy && typeof legacy === 'object') {
|
|
679
|
+
logger.warn('[Rocom] ingame/merchant/info 不可用,已回退 merchant/info');
|
|
680
|
+
return { ...legacy, _source: 'legacy' };
|
|
681
|
+
}
|
|
682
|
+
return null;
|
|
618
683
|
}
|
|
619
684
|
async queryPetSize(ctx, diameter, weight, pool = 'magic', pageNo = 1, pageSize = 30, userIdentifier = '') {
|
|
620
685
|
const params = this.scopedParams({
|
|
@@ -627,6 +692,55 @@ class RocomClient {
|
|
|
627
692
|
}, userIdentifier);
|
|
628
693
|
return this.get(ctx, '/api/v1/games/rocom/wiki/pet-size/query', this.wegameHeaders('', userIdentifier, 'bot', 'koishi'), params);
|
|
629
694
|
}
|
|
695
|
+
// 后端查蛋:按展示身高/体重查询,参数名是 height/weight。
|
|
696
|
+
async searchEggBySize(ctx, heightMeters, weightKg, pageNo = 1, pageSize = 30, userIdentifier = '') {
|
|
697
|
+
const params = this.scopedParams({
|
|
698
|
+
height: heightMeters,
|
|
699
|
+
weight: weightKg,
|
|
700
|
+
page_no: Math.max(Number(pageNo) || 1, 1),
|
|
701
|
+
page_size: Math.min(Math.max(Number(pageSize) || 30, 1), 100),
|
|
702
|
+
}, userIdentifier);
|
|
703
|
+
return this.get(ctx, '/api/v1/games/rocom/egg/search', this.wegameHeaders('', userIdentifier, 'bot', 'koishi'), params);
|
|
704
|
+
}
|
|
705
|
+
// 异色/炫彩收集排行榜。
|
|
706
|
+
async getPetCollectionRanking(ctx, rankType, limit = 10, uid = '', options = {}) {
|
|
707
|
+
if (!['shining', 'glass'].includes(rankType)) {
|
|
708
|
+
this.setLastError('无效榜单类型');
|
|
709
|
+
return null;
|
|
710
|
+
}
|
|
711
|
+
if (!Number.isInteger(limit) || limit < 1 || limit > 50) {
|
|
712
|
+
this.setLastError('无效数量');
|
|
713
|
+
return null;
|
|
714
|
+
}
|
|
715
|
+
const params = { limit, resolve_names: '1' };
|
|
716
|
+
if (uid)
|
|
717
|
+
params.uid = this.sanitizeUid(uid);
|
|
718
|
+
return this.get(ctx, `/api/v1/games/rocom/ingame/player/card/pet-stats/rankings/${rankType}`, this.wegameHeaders('', options.userIdentifier || '', 'bot', 'koishi'), this.scopedParams(params, options.userIdentifier || ''));
|
|
719
|
+
}
|
|
720
|
+
// 阵容分享码解析与历史查询。
|
|
721
|
+
async parseShareCode(ctx, shareCode, userIdentifier = '') {
|
|
722
|
+
const code = String(shareCode || '').trim();
|
|
723
|
+
if (!code) {
|
|
724
|
+
this.setLastError('分享码不能为空');
|
|
725
|
+
return null;
|
|
726
|
+
}
|
|
727
|
+
return this.post(ctx, '/api/v1/games/rocom/tools/share-code/parse', this.wegameHeaders('', userIdentifier, 'bot', 'koishi'), { share_code: code }, this.scopedParams({}, userIdentifier));
|
|
728
|
+
}
|
|
729
|
+
async getShareCodeRecords(ctx, options = {}, userIdentifier = '') {
|
|
730
|
+
const params = {
|
|
731
|
+
page_no: Math.max(Number(options.pageNo) || 1, 1),
|
|
732
|
+
page_size: Math.min(Math.max(Number(options.pageSize) || 20, 1), 100),
|
|
733
|
+
};
|
|
734
|
+
if (options.shareCode)
|
|
735
|
+
params.share_code = String(options.shareCode).trim();
|
|
736
|
+
if (options.hash)
|
|
737
|
+
params.hash = String(options.hash).trim();
|
|
738
|
+
if (options.modeId !== undefined)
|
|
739
|
+
params.mode_id = options.modeId;
|
|
740
|
+
if (options.magicId !== undefined)
|
|
741
|
+
params.magic_id = options.magicId;
|
|
742
|
+
return this.get(ctx, '/api/v1/games/rocom/tools/share-code/records', this.wegameHeaders('', userIdentifier, 'bot', 'koishi'), this.scopedParams(params, userIdentifier));
|
|
743
|
+
}
|
|
630
744
|
async getActivitiesInfo(ctx, refresh = false, userIdentifier = '') {
|
|
631
745
|
return this.get(ctx, '/api/v1/games/rocom/activities/info', this.wegameHeaders('', userIdentifier, 'bot', 'koishi'), this.scopedParams({ refresh: refresh ? 'true' : 'false' }, userIdentifier));
|
|
632
746
|
}
|
|
@@ -636,8 +750,8 @@ class RocomClient {
|
|
|
636
750
|
async getAnnouncementList(ctx, params = {}, userIdentifier = '') {
|
|
637
751
|
return this.get(ctx, '/api/v1/games/rocom/announcement/list', this.wegameHeaders('', userIdentifier, 'bot', 'koishi'), this.scopedParams(params, userIdentifier));
|
|
638
752
|
}
|
|
639
|
-
async getLatestAnnouncement(ctx, params = {}, userIdentifier = '') {
|
|
640
|
-
return this.get(ctx, '/api/v1/games/rocom/announcement/latest', this.wegameHeaders('', userIdentifier, 'bot', 'koishi'), this.scopedParams(params, userIdentifier));
|
|
753
|
+
async getLatestAnnouncement(ctx, params = {}, userIdentifier = '', signal) {
|
|
754
|
+
return this.get(ctx, '/api/v1/games/rocom/announcement/latest', this.wegameHeaders('', userIdentifier, 'bot', 'koishi'), this.scopedParams(params, userIdentifier), { signal });
|
|
641
755
|
}
|
|
642
756
|
async getAnnouncementDetail(ctx, threadId, userIdentifier = '') {
|
|
643
757
|
return this.get(ctx, '/api/v1/games/rocom/announcement/detail', this.wegameHeaders('', userIdentifier, 'bot', 'koishi'), this.scopedParams({ thread_id: threadId }, userIdentifier));
|
|
@@ -684,41 +798,82 @@ class RocomClient {
|
|
|
684
798
|
}
|
|
685
799
|
async ingameHomeInfo(ctx, uid, options = {}) {
|
|
686
800
|
const sanitizedUid = this.sanitizeUid(uid);
|
|
687
|
-
if (!sanitizedUid) {
|
|
801
|
+
if (!sanitizedUid && !options.auth?.fwToken) {
|
|
688
802
|
this.setLastError('UID 不能为空');
|
|
689
803
|
return null;
|
|
690
804
|
}
|
|
691
805
|
const waitMs = Number(options.waitMs) || 5000;
|
|
692
806
|
const path = '/api/v1/games/rocom/ingame/home/info';
|
|
693
|
-
const payload = {
|
|
694
|
-
|
|
695
|
-
|
|
807
|
+
const payload = { wait_ms: waitMs };
|
|
808
|
+
if (sanitizedUid)
|
|
809
|
+
payload.uid = sanitizedUid;
|
|
810
|
+
return this.queuedQuery(ctx, path, payload, options, {
|
|
696
811
|
queuedNoTaskId: '家园查询任务已入队,但未返回 task_id',
|
|
697
812
|
stillQueued: (taskId) => `家园查询任务仍在排队,请稍后重试(task_id: ${taskId})`,
|
|
698
813
|
});
|
|
699
814
|
}
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
815
|
+
// 远行商人实时接口:优先 ingame live,返回 goods/shop/meta 或任务轮询结果。
|
|
816
|
+
// 未指定商店时不传 shop_id;调用方负责在新接口不可用时回退旧 merchant/info。
|
|
817
|
+
async ingameMerchantInfo(ctx, shopId, options = {}) {
|
|
818
|
+
const waitMs = Number(options.waitMs) || 5000;
|
|
819
|
+
const payload = { wait_ms: waitMs };
|
|
820
|
+
if (shopId !== undefined && shopId !== null && String(shopId) !== '')
|
|
821
|
+
payload.shop_id = shopId;
|
|
822
|
+
return this.queuedQuery(ctx, '/api/v1/games/rocom/ingame/merchant/info', payload, options, {
|
|
823
|
+
queuedNoTaskId: '远行商人任务已入队,但未返回 task_id',
|
|
824
|
+
stillQueued: (taskId) => `远行商人任务仍在排队,请稍后重试(task_id: ${taskId})`,
|
|
825
|
+
});
|
|
826
|
+
}
|
|
827
|
+
// 家园蛋状态轻量接口:只返回蛋相关数据,供蛋状态订阅轮询与即时查询。
|
|
828
|
+
async ingameHomeEggs(ctx, uid, options = {}) {
|
|
829
|
+
const sanitizedUid = this.sanitizeUid(uid);
|
|
830
|
+
if (!sanitizedUid && !options.auth?.fwToken) {
|
|
831
|
+
this.setLastError('UID 不能为空');
|
|
832
|
+
return null;
|
|
833
|
+
}
|
|
834
|
+
const waitMs = Number(options.waitMs) || 5000;
|
|
835
|
+
const payload = { wait_ms: waitMs };
|
|
836
|
+
if (sanitizedUid)
|
|
837
|
+
payload.uid = sanitizedUid;
|
|
838
|
+
return this.queuedQuery(ctx, '/api/v1/games/rocom/ingame/home/eggs', payload, options, {
|
|
839
|
+
queuedNoTaskId: '家园蛋状态任务已入队,但未返回 task_id',
|
|
840
|
+
stillQueued: (taskId) => `家园蛋状态任务仍在排队,请稍后重试(task_id: ${taskId})`,
|
|
841
|
+
});
|
|
842
|
+
}
|
|
843
|
+
// 家园精灵列表:走 home/pet-data 路径,返回侧重体重和声音的精灵一览。
|
|
844
|
+
async ingameHomePetData(ctx, uid, options = {}) {
|
|
845
|
+
const sanitizedUid = this.sanitizeUid(uid);
|
|
846
|
+
if (!sanitizedUid && !options.auth?.fwToken) {
|
|
847
|
+
this.setLastError('UID 不能为空');
|
|
848
|
+
return null;
|
|
849
|
+
}
|
|
850
|
+
const waitMs = Number(options.waitMs) || 20000;
|
|
851
|
+
const payload = { wait_ms: waitMs };
|
|
852
|
+
if (sanitizedUid)
|
|
853
|
+
payload.uid = sanitizedUid;
|
|
854
|
+
return this.queuedQuery(ctx, '/api/v1/games/rocom/ingame/home/pet-data', payload, options, {
|
|
855
|
+
queuedNoTaskId: '家园精灵查询任务已入队,但未返回 task_id',
|
|
856
|
+
stillQueued: (taskId) => `家园精灵查询任务仍在排队,请稍后重试(task_id: ${taskId})`,
|
|
857
|
+
});
|
|
704
858
|
}
|
|
705
|
-
// 家园详情:批量或单只查询家园摆放精灵的完整 ingame
|
|
859
|
+
// 家园详情:批量或单只查询家园摆放精灵的完整 ingame 数据。
|
|
706
860
|
// UID 参数名为 target_uin;单只查询需同时提供 pet_gid 和 npc_id。
|
|
707
861
|
async ingamePetData(ctx, uid, extras = {}, options = {}) {
|
|
708
862
|
const sanitizedUid = this.sanitizeUid(uid);
|
|
709
|
-
if (!sanitizedUid) {
|
|
863
|
+
if (!sanitizedUid && !options.auth?.fwToken) {
|
|
710
864
|
this.setLastError('UID 不能为空');
|
|
711
865
|
return null;
|
|
712
866
|
}
|
|
713
867
|
const waitMs = Number(options.waitMs) || 20000;
|
|
714
|
-
const payload = {
|
|
868
|
+
const payload = { wait_ms: waitMs };
|
|
869
|
+
if (sanitizedUid)
|
|
870
|
+
payload.target_uin = sanitizedUid;
|
|
715
871
|
if (extras.petGid !== undefined && extras.petGid !== null && String(extras.petGid) !== '')
|
|
716
872
|
payload.pet_gid = extras.petGid;
|
|
717
873
|
if (extras.npcId !== undefined && extras.npcId !== null && String(extras.npcId) !== '')
|
|
718
874
|
payload.npc_id = extras.npcId;
|
|
719
875
|
const path = '/api/v1/games/rocom/ingame/pet/data';
|
|
720
|
-
|
|
721
|
-
return this.pollIngameTask(ctx, first, options, {
|
|
876
|
+
return this.queuedQuery(ctx, path, payload, options, {
|
|
722
877
|
queuedNoTaskId: '家园详情任务已入队,但未返回 task_id',
|
|
723
878
|
stillQueued: (taskId) => `家园详情任务仍在排队,请稍后重试(task_id: ${taskId})`,
|
|
724
879
|
});
|
|
@@ -754,7 +909,7 @@ class RocomClient {
|
|
|
754
909
|
params.name = options.name;
|
|
755
910
|
return this.get(ctx, '/api/v1/games/rocom/pet/detail', this.wegameHeaders(), params);
|
|
756
911
|
}
|
|
757
|
-
// ===== 新版 RoCom Wiki API
|
|
912
|
+
// ===== 新版 RoCom Wiki API=====
|
|
758
913
|
wikiPagedParams(q = '', pageNo = 1, pageSize = 10, filters = {}) {
|
|
759
914
|
const params = {
|
|
760
915
|
page_no: Math.max(Number(pageNo) || 1, 1),
|