@newbeebox/newbeebox-client-web-sdk 1.0.10 → 1.0.13

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/README.md CHANGED
@@ -45,7 +45,7 @@ console.log(info);
45
45
 
46
46
  获取当前用户的订阅信息。
47
47
 
48
- #### `InstallWoWAddon(game_version_id, addon_id): Promise<any>`
48
+ #### `InstallWoWAddon(game_version_id, addon_id, secret_key?): Promise<any>`
49
49
 
50
50
  安装魔兽世界插件。
51
51
 
@@ -53,6 +53,7 @@ console.log(info);
53
53
  |------|------|------|
54
54
  | game_version_id | string \| number | 游戏版本ID |
55
55
  | addon_id | string \| number | 插件ID |
56
+ | secret_key | string | 密钥(可选) |
56
57
 
57
58
  #### `Patch(tool_name, data?): Promise<any>`
58
59
 
package/index.js CHANGED
@@ -1,11 +1,110 @@
1
+ // 当前 SDK 版本号(发布新版本时请同步 package.json 的 version 字段)
2
+ const SDK_VERSION = "1.0.13";
1
3
  // 设置超时时间
2
4
  const CLIENT_CHECK_TIMEOUT = 200; // 0.2秒
3
5
  // 任务超时时间
4
6
  const TASK_REQUEST_TIMEOUT = 1000; // 1秒
5
7
  // 客户端可能使用的端口列表
6
- const LOCAL_PORT_LIST = [35560, 35561, 35562, 35563, 35564, 35565, 35566, 35567, 35568, 35569, 35570, 35571, 35572, 35573, 35574, 35575, 35576, 35577, 35578, 35579];
8
+ // 原始端口列表(兼容已部署的老 SDK,必须保留且优先)
9
+ const LEGACY_PORT_LIST = [
10
+ 35560, 35561, 35562, 35563, 35564, 35565, 35566, 35567, 35568, 35569,
11
+ 35570, 35571, 35572, 35573, 35574, 35575, 35576, 35577, 35578, 35579,
12
+ ];
13
+ // 新增端口列表(抗端口被整段占用,分散在多个不相邻区间)
14
+ const EXTRA_PORT_LIST = [
15
+ 1278, 6817, 11456, 14923, 19372, 23814, 28651, 33279, 41537, 46813,
16
+ ];
17
+ // 实际使用的候选端口:原始端口优先,其后接新增端口
18
+ const LOCAL_PORT_LIST = [...LEGACY_PORT_LIST, ...EXTRA_PORT_LIST];
7
19
  // 服务端地址
8
20
  const CLIENT_SERVICE_BASE_URL = "http://127.0.0.1";
21
+
22
+ // 端口缓存的 key
23
+ const PORT_CACHE_KEY = "nbb_client_port";
24
+ // 内存兜底缓存:用于没有 localStorage 的环境(Electron 主进程 / Node / 受限 webview)
25
+ let _memPortCache = null;
26
+
27
+ // 读取缓存端口:优先 localStorage,不可用时回退内存缓存(兼容浏览器/Electron/Tauri/Node)
28
+ function readPortCache() {
29
+ try {
30
+ if (typeof localStorage !== "undefined" && localStorage) {
31
+ const v = localStorage.getItem(PORT_CACHE_KEY);
32
+ if (v) return Number(v) || null;
33
+ }
34
+ } catch (e) { /* localStorage 不可用,忽略,走内存缓存 */ }
35
+ return _memPortCache;
36
+ }
37
+
38
+ // 写入缓存端口:内存 + localStorage(若可用)
39
+ function writePortCache(port) {
40
+ _memPortCache = port;
41
+ try {
42
+ if (typeof localStorage !== "undefined" && localStorage) {
43
+ localStorage.setItem(PORT_CACHE_KEY, String(port));
44
+ }
45
+ } catch (e) { /* 忽略 */ }
46
+ }
47
+
48
+ // 清除缓存端口
49
+ function clearPortCache() {
50
+ _memPortCache = null;
51
+ try {
52
+ if (typeof localStorage !== "undefined" && localStorage) {
53
+ localStorage.removeItem(PORT_CACHE_KEY);
54
+ }
55
+ } catch (e) { /* 忽略 */ }
56
+ }
57
+
58
+ // 探测单个端口的 /ping:成功 resolve(port),失败 reject
59
+ function pingPort(port) {
60
+ return new Promise((resolve, reject) => {
61
+ const controller = new AbortController();
62
+ const timeoutId = setTimeout(() => controller.abort(), CLIENT_CHECK_TIMEOUT);
63
+ fetch(CLIENT_SERVICE_BASE_URL + ":" + port + "/ping", {
64
+ method: "GET",
65
+ signal: controller.signal,
66
+ })
67
+ .then((response) => response.json())
68
+ .then((data) => {
69
+ clearTimeout(timeoutId);
70
+ if (data && data.code === 1) resolve(port);
71
+ else reject(new Error("not newbee client"));
72
+ })
73
+ .catch((e) => {
74
+ clearTimeout(timeoutId);
75
+ reject(e);
76
+ });
77
+ });
78
+ }
79
+
80
+ // 并行探测多个端口,返回第一个成功的端口
81
+ // 不依赖 Promise.any(ES2021),自己实现以兼容老版本 webview
82
+ function probeFirstPort(ports) {
83
+ return new Promise((resolve, reject) => {
84
+ let pending = ports.length;
85
+ if (pending === 0) {
86
+ reject(new Error("no candidate ports"));
87
+ return;
88
+ }
89
+ let settled = false;
90
+ ports.forEach((port) => {
91
+ pingPort(port)
92
+ .then((p) => {
93
+ if (!settled) {
94
+ settled = true;
95
+ resolve(p);
96
+ }
97
+ })
98
+ .catch(() => {
99
+ pending--;
100
+ if (pending === 0 && !settled) {
101
+ reject(new Error("all ports failed"));
102
+ }
103
+ });
104
+ });
105
+ });
106
+ }
107
+
9
108
  export class NewBeeClient {
10
109
  app_id = "";
11
110
 
@@ -21,47 +120,32 @@ export class NewBeeClient {
21
120
  }
22
121
 
23
122
  async Init(app_id) {
123
+ console.log(`[NewBeeBox SDK] version ${SDK_VERSION}`);
124
+
24
125
  if (!app_id || typeof app_id !== "string") {
25
126
  throw new Error("APPID格式不正确 请前往后台获取");
26
127
  }
27
128
 
28
129
  this.app_id = app_id;
29
130
 
30
- for (const port of LOCAL_PORT_LIST) {
31
- // 创建 AbortController 实例
32
- const controller = new AbortController();
33
-
34
- const signal = controller.signal;
35
-
36
- let check_response;
37
-
38
- const timeoutId = setTimeout(() => {
39
- controller.abort(); // 超时后取消请求
40
- console.log("端口:", port, '请求超时');
41
- }, CLIENT_CHECK_TIMEOUT);
42
-
131
+ // 1) 先试缓存端口:命中直接用,重连最快且不打扰其他端口
132
+ const cachedPort = readPortCache();
133
+ if (cachedPort) {
43
134
  try {
44
- let response = await fetch( CLIENT_SERVICE_BASE_URL + (port ? ":" + port : "") + "/ping", {
45
- method: "GET",
46
- signal: signal
47
- });
48
-
49
- check_response = await response.json();
50
-
51
- clearTimeout(timeoutId);
135
+ this.newbee_client_port = await pingPort(cachedPort);
136
+ console.log("客户端开启的端口号(缓存命中):", this.newbee_client_port);
137
+ return;
52
138
  } catch (e) {
53
- console.error(port, "端口检查失败:", e);
54
- }
55
-
56
- console.log("端口检查:", check_response);
57
-
58
- if (check_response && check_response.code === 1) {
59
- this.newbee_client_port = port;
60
- break;
139
+ clearPortCache(); // 缓存失效,继续全量探测
61
140
  }
62
141
  }
63
142
 
64
- if (!this.newbee_client_port) {
143
+ // 2) 并行探测全部候选端口,取第一个成功的(老端口段 + 分散端口)
144
+ try {
145
+ this.newbee_client_port = await probeFirstPort(LOCAL_PORT_LIST);
146
+ writePortCache(this.newbee_client_port);
147
+ } catch (e) {
148
+ clearPortCache();
65
149
  throw new Error("未检测到新手盒子客户端 初始化失败");
66
150
  }
67
151
 
@@ -145,21 +229,25 @@ export class NewBeeClient {
145
229
  }
146
230
 
147
231
  // 安装魔兽世界插件
148
- async InstallWoWAddon(game_version_id, addon_id) {
232
+ async InstallWoWAddon(game_version_id, addon_id, secret_key) {
149
233
  this._ensureInitialized();
150
234
 
151
235
  let install_response = null;
152
236
  try {
237
+ const body = {
238
+ app_id: this.app_id,
239
+ game_version_id: game_version_id,
240
+ addon_id: addon_id
241
+ };
242
+ if (secret_key) {
243
+ body.secret_key = secret_key;
244
+ }
153
245
  let response = await fetch(CLIENT_SERVICE_BASE_URL + ":" + this.newbee_client_port + "/tool/wow_install_addon", {
154
246
  method: "POST",
155
247
  headers: {
156
248
  "Content-Type": 'application/json',
157
249
  },
158
- body: JSON.stringify({
159
- app_id: this.app_id,
160
- game_version_id: game_version_id,
161
- addon_id: addon_id
162
- })
250
+ body: JSON.stringify(body)
163
251
  });
164
252
 
165
253
  install_response = await response.json();
package/package.json CHANGED
@@ -1,29 +1,29 @@
1
- {
2
- "name": "@newbeebox/newbeebox-client-web-sdk",
3
- "version": "1.0.10",
4
- "description": "NewBeeBox Client SDK for Web",
5
- "main": "index.js",
6
- "type": "module",
7
- "types": "./types/index.d.ts",
8
- "files": [
9
- "*.js",
10
- "types/*.d.ts"
11
- ],
12
- "scripts": {
13
- "release:patch": "npm version patch && npm publish",
14
- "release:minor": "npm version minor && npm publish",
15
- "release:major": "npm version major && npm publish"
16
- },
17
- "keywords": [
18
- "newbeebox",
19
- "wow",
20
- "sdk",
21
- "client"
22
- ],
23
- "author": "NewBeeBoxTeam",
24
- "license": "ISC",
25
- "publishConfig": {
26
- "registry": "https://registry.npmjs.org/",
27
- "access": "public"
28
- }
29
- }
1
+ {
2
+ "name": "@newbeebox/newbeebox-client-web-sdk",
3
+ "version": "1.0.13",
4
+ "description": "NewBeeBox Client SDK for Web",
5
+ "main": "index.js",
6
+ "type": "module",
7
+ "types": "./types/index.d.ts",
8
+ "files": [
9
+ "*.js",
10
+ "types/*.d.ts"
11
+ ],
12
+ "scripts": {
13
+ "release:patch": "npm version patch && npm publish",
14
+ "release:minor": "npm version minor && npm publish",
15
+ "release:major": "npm version major && npm publish"
16
+ },
17
+ "keywords": [
18
+ "newbeebox",
19
+ "wow",
20
+ "sdk",
21
+ "client"
22
+ ],
23
+ "author": "NewBeeBoxTeam",
24
+ "license": "ISC",
25
+ "publishConfig": {
26
+ "registry": "https://registry.npmjs.org/",
27
+ "access": "public"
28
+ }
29
+ }
package/types/index.d.ts CHANGED
@@ -37,10 +37,11 @@ export class NewBeeClient {
37
37
  /**
38
38
  * 安装魔兽世界插件
39
39
  * @param game_version_id 游戏版本ID
40
- * @param mod_id 插件ID
40
+ * @param addon_id 插件ID
41
+ * @param secret_key 密钥(可选)
41
42
  * @return {Promise<any>}
42
43
  */
43
- InstallWoWAddon(game_version_id: string | number, mod_id: string | number): Promise<any>;
44
+ InstallWoWAddon(game_version_id: string | number, addon_id: string | number, secret_key?: string): Promise<any>;
44
45
 
45
46
  /**
46
47
  * 通用请求接口