gamerpc 9.0.0 → 9.0.1

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.
@@ -0,0 +1,444 @@
1
+ /**
2
+ * secp256k1 加密单元测试
3
+ * 使用已知测试向量,验证 @noble/secp256k1 封装层与 elliptic 的等价性
4
+ *
5
+ * 测试向量来源:
6
+ * - RFC 6979 (Deterministic ECDSA)
7
+ * - Bitcoin BIP32 test vectors
8
+ * - secp256k1 标准测试向量
9
+ */
10
+ const assert = require('assert');
11
+ const secp = require('../../src/utils/secp256k1');
12
+
13
+ // ============================================================
14
+ // Helper
15
+ // ============================================================
16
+ const hex = (buf) => Buffer.isBuffer(buf) ? buf.toString('hex') : buf;
17
+
18
+ describe('secp256k1 封装层单元测试', function () {
19
+
20
+ // ==========================================================
21
+ // 1. 密钥生成
22
+ // ==========================================================
23
+ describe('密钥生成', function () {
24
+ it('generatePrivateKey: 生成 32 字节私钥', function () {
25
+ const priv = secp.generatePrivateKey();
26
+ assert(Buffer.isBuffer(priv));
27
+ assert.strictEqual(priv.length, 32);
28
+ });
29
+
30
+ it('generatePrivateKey: 连续两次生成的私钥不同', function () {
31
+ const a = secp.generatePrivateKey();
32
+ const b = secp.generatePrivateKey();
33
+ assert(!a.equals(b));
34
+ });
35
+
36
+ it('privateKeyVerify: 有效私钥返回 true', function () {
37
+ const priv = secp.generatePrivateKey();
38
+ assert.strictEqual(secp.privateKeyVerify(priv), true);
39
+ });
40
+
41
+ it('privateKeyVerify: 全零私钥返回 false', function () {
42
+ assert.strictEqual(secp.privateKeyVerify(Buffer.alloc(32, 0)), false);
43
+ });
44
+
45
+ it('privateKeyVerify: 超范围私钥返回 false', function () {
46
+ // n = FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141
47
+ const n = Buffer.from('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141', 'hex');
48
+ assert.strictEqual(secp.privateKeyVerify(n), false);
49
+ });
50
+
51
+ it('privateKeyVerify: 长度不是 32 返回 false', function () {
52
+ assert.strictEqual(secp.privateKeyVerify(Buffer.alloc(31, 1)), false);
53
+ assert.strictEqual(secp.privateKeyVerify(Buffer.alloc(33, 1)), false);
54
+ });
55
+ });
56
+
57
+ // ==========================================================
58
+ // 2. 公钥创建与验证
59
+ // ==========================================================
60
+ describe('公钥操作', function () {
61
+ // 已知测试向量:私钥 1 → 压缩公钥
62
+ // priv=1 → pub=0279BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798
63
+ const PRIV_ONE = Buffer.from('0000000000000000000000000000000000000000000000000000000000000001', 'hex');
64
+ const PUB_ONE_COMPRESSED = '0279BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798'.toLowerCase();
65
+ const PUB_ONE_UNCOMPRESSED = '0479BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8'.toLowerCase();
66
+
67
+ it('publicKeyCreate: 已知私钥生成压缩公钥', function () {
68
+ const pub = secp.publicKeyCreate(PRIV_ONE, true);
69
+ assert.strictEqual(hex(pub), PUB_ONE_COMPRESSED);
70
+ });
71
+
72
+ it('publicKeyCreate: 已知私钥生成非压缩公钥', function () {
73
+ const pub = secp.publicKeyCreate(PRIV_ONE, false);
74
+ assert.strictEqual(hex(pub), PUB_ONE_UNCOMPRESSED);
75
+ });
76
+
77
+ it('publicKeyCreate: 默认生成压缩公钥', function () {
78
+ const pub = secp.publicKeyCreate(PRIV_ONE);
79
+ assert.strictEqual(pub.length, 33);
80
+ });
81
+
82
+ it('publicKeyConvert: 压缩→非压缩', function () {
83
+ const compressed = secp.publicKeyCreate(PRIV_ONE, true);
84
+ const uncompressed = secp.publicKeyConvert(compressed, false);
85
+ assert.strictEqual(hex(uncompressed), PUB_ONE_UNCOMPRESSED);
86
+ });
87
+
88
+ it('publicKeyConvert: 非压缩→压缩', function () {
89
+ const uncompressed = secp.publicKeyCreate(PRIV_ONE, false);
90
+ const compressed = secp.publicKeyConvert(uncompressed, true);
91
+ assert.strictEqual(hex(compressed), PUB_ONE_COMPRESSED);
92
+ });
93
+
94
+ it('publicKeyVerify: 有效公钥返回 true', function () {
95
+ assert.strictEqual(secp.publicKeyVerify(Buffer.from(PUB_ONE_COMPRESSED, 'hex')), true);
96
+ assert.strictEqual(secp.publicKeyVerify(Buffer.from(PUB_ONE_UNCOMPRESSED, 'hex')), true);
97
+ });
98
+
99
+ it('publicKeyVerify: 无效公钥返回 false', function () {
100
+ assert.strictEqual(secp.publicKeyVerify(Buffer.alloc(33, 0)), false);
101
+ assert.strictEqual(secp.publicKeyVerify(Buffer.alloc(0)), false);
102
+ });
103
+
104
+ it('generateKey → publicKeyCreate: 生成密钥对一致性', function () {
105
+ for (let i = 0; i < 10; i++) {
106
+ const priv = secp.generatePrivateKey();
107
+ const pubC = secp.publicKeyCreate(priv, true);
108
+ const pubU = secp.publicKeyCreate(priv, false);
109
+ // 验证压缩/非压缩表示同一公钥
110
+ const converted = secp.publicKeyConvert(pubC, false);
111
+ assert.strictEqual(hex(converted), hex(pubU));
112
+ }
113
+ });
114
+ });
115
+
116
+ // ==========================================================
117
+ // 3. 签名与验证 (RFC 6979 确定性签名)
118
+ // ==========================================================
119
+ describe('签名与验证', function () {
120
+ // RFC 6979 Appendix A.2.5 测试向量
121
+ // SHA-256("sample")
122
+ const RFC6979_PRIV = Buffer.from('C9AFA9D845BA75166B5C215767B1D6934E50C3DB36E89B127B8A622B120F6721', 'hex');
123
+ const RFC6979_MSG = Buffer.from('AF2BDBE1AA9B6EC1E2ADE1D694F41FC71A831D0268E9891562113D8A62ADD1BF', 'hex');
124
+ // 这个私钥对 "sample" 签名应该能验证
125
+ const SAMPLE_HASH = Buffer.from('AF2BDBE1AA9B6EC1E2ADE1D694F41FC71A831D0268E9891562113D8A62ADD1BF', 'hex');
126
+
127
+ it('sign: 生成 DER 签名', function () {
128
+ const sig = secp.sign(SAMPLE_HASH, RFC6979_PRIV);
129
+ assert(Buffer.isBuffer(sig));
130
+ // DER 签名长度大约 70-73 字节
131
+ assert(sig.length >= 68 && sig.length <= 73, `unexpected sig length: ${sig.length}`);
132
+ });
133
+
134
+ it('sign → verify: 签名后可成功验证 (同一密钥)', function () {
135
+ const priv = secp.generatePrivateKey();
136
+ const pub = secp.publicKeyCreate(priv, true);
137
+ const msg = secp.generatePrivateKey(); // 32 random bytes
138
+
139
+ const sig = secp.sign(msg, priv);
140
+ const result = secp.verify(msg, sig, pub);
141
+ assert.strictEqual(result, true);
142
+ });
143
+
144
+ it('verify: 错误公钥无法验证', function () {
145
+ const privA = secp.generatePrivateKey();
146
+ const privB = secp.generatePrivateKey();
147
+ const pubB = secp.publicKeyCreate(privB, true);
148
+ const msg = secp.generatePrivateKey();
149
+
150
+ const sig = secp.sign(msg, privA);
151
+ const result = secp.verify(msg, sig, pubB);
152
+ assert.strictEqual(result, false);
153
+ });
154
+
155
+ it('verify: 篡改消息无法验证', function () {
156
+ const priv = secp.generatePrivateKey();
157
+ const pub = secp.publicKeyCreate(priv, true);
158
+ const msg = secp.generatePrivateKey();
159
+
160
+ const sig = secp.sign(msg, priv);
161
+ const tampered = Buffer.from(msg);
162
+ tampered[0] ^= 1;
163
+ const result = secp.verify(tampered, sig, pub);
164
+ assert.strictEqual(result, false);
165
+ });
166
+
167
+ it('verify: 空签名返回 false', function () {
168
+ const priv = secp.generatePrivateKey();
169
+ const pub = secp.publicKeyCreate(priv, true);
170
+ const msg = secp.generatePrivateKey();
171
+ assert.strictEqual(secp.verify(msg, Buffer.alloc(0), pub), false);
172
+ });
173
+
174
+ it('verify: 空公钥返回 false', function () {
175
+ const priv = secp.generatePrivateKey();
176
+ const msg = secp.generatePrivateKey();
177
+ const sig = secp.sign(msg, priv);
178
+ assert.strictEqual(secp.verify(msg, sig, Buffer.alloc(0)), false);
179
+ });
180
+
181
+ it('确定性: 同一消息和私钥产生相同签名', function () {
182
+ const priv = secp.generatePrivateKey();
183
+ const msg = secp.generatePrivateKey();
184
+ const sig1 = secp.sign(msg, priv);
185
+ const sig2 = secp.sign(msg, priv);
186
+ assert(hex(sig1) === hex(sig2), 'deterministic signatures must be identical');
187
+ });
188
+
189
+ it('不同消息产生不同签名', function () {
190
+ const priv = secp.generatePrivateKey();
191
+ const msg1 = secp.generatePrivateKey();
192
+ const msg2 = secp.generatePrivateKey();
193
+ // 确保消息不同
194
+ while (msg1.equals(msg2)) {
195
+ msg2.fill(0);
196
+ msg2[0] = msg1[0] ^ 0xFF;
197
+ }
198
+ const sig1 = secp.sign(msg1, priv);
199
+ const sig2 = secp.sign(msg2, priv);
200
+ assert(!sig1.equals(sig2));
201
+ });
202
+ });
203
+
204
+ // ==========================================================
205
+ // 4. DER 格式转换
206
+ // ==========================================================
207
+ describe('DER 格式转换', function () {
208
+ it('toDER → fromDER: 往返转换', function () {
209
+ const priv = secp.generatePrivateKey();
210
+ const msg = secp.generatePrivateKey();
211
+ const der = secp.sign(msg, priv);
212
+
213
+ const compact = secp.fromDER(der);
214
+ assert.strictEqual(compact.length, 64);
215
+
216
+ const der2 = secp.toDER(compact);
217
+ // 重新解析验证
218
+ const compact2 = secp.fromDER(der2);
219
+ assert.strictEqual(hex(compact), hex(compact2));
220
+ });
221
+
222
+ it('toDER → verify: 往返后可验证', function () {
223
+ const priv = secp.generatePrivateKey();
224
+ const pub = secp.publicKeyCreate(priv, true);
225
+ const msg = secp.generatePrivateKey();
226
+ const der = secp.sign(msg, priv);
227
+
228
+ const compact = secp.fromDER(der);
229
+ const der2 = secp.toDER(compact);
230
+
231
+ assert.strictEqual(secp.verify(msg, der2, pub), true);
232
+ });
233
+
234
+ it('fromDER: 无效输入不崩溃', function () {
235
+ // 无效 DER 应该抛出或返回异常值
236
+ try {
237
+ secp.fromDER(Buffer.alloc(10, 0xFF));
238
+ // 如果没抛异常也是可以接受的,只要不崩溃
239
+ } catch (e) {
240
+ // 预期可能抛异常
241
+ }
242
+ });
243
+
244
+ it('toDER → isLowS: 低S值验证', function () {
245
+ const priv = secp.generatePrivateKey();
246
+ const msg = secp.generatePrivateKey();
247
+ const der = secp.sign(msg, priv);
248
+ assert.strictEqual(secp.isLowS(der), true, 'normal signature should have low S');
249
+ });
250
+
251
+ it('isLowS: 无效输入返回 false', function () {
252
+ assert.strictEqual(secp.isLowS(Buffer.alloc(0)), false);
253
+ assert.strictEqual(secp.isLowS(Buffer.alloc(10, 0xFF)), false);
254
+ });
255
+ });
256
+
257
+ // ==========================================================
258
+ // 5. ECDH 密钥交换
259
+ // ==========================================================
260
+ describe('ECDH 密钥交换', function () {
261
+ it('ecdh: 双方计算得到相同的共享密钥', function () {
262
+ const privA = secp.generatePrivateKey();
263
+ const privB = secp.generatePrivateKey();
264
+ const pubA = secp.publicKeyCreate(privA, true);
265
+ const pubB = secp.publicKeyCreate(privB, true);
266
+
267
+ const sharedA = secp.ecdh(pubB, privA); // A用B的公钥+自己的私钥
268
+ const sharedB = secp.ecdh(pubA, privB); // B用A的公钥+自己的私钥
269
+
270
+ assert.strictEqual(hex(sharedA), hex(sharedB));
271
+ });
272
+
273
+ it('ecdh: 返回 32 字节', function () {
274
+ const privA = secp.generatePrivateKey();
275
+ const privB = secp.generatePrivateKey();
276
+ const pubB = secp.publicKeyCreate(privB, true);
277
+
278
+ const shared = secp.ecdh(pubB, privA);
279
+ assert.strictEqual(shared.length, 32);
280
+ });
281
+
282
+ it('ecdh: 不同密钥对产生不同共享密钥', function () {
283
+ const p1 = secp.generatePrivateKey();
284
+ const p2 = secp.generatePrivateKey();
285
+ const p3 = secp.generatePrivateKey();
286
+ const pub2 = secp.publicKeyCreate(p2, true);
287
+ const pub3 = secp.publicKeyCreate(p3, true);
288
+
289
+ const s12 = secp.ecdh(pub2, p1);
290
+ const s13 = secp.ecdh(pub3, p1);
291
+ assert(!s12.equals(s13));
292
+ });
293
+ });
294
+
295
+ // ==========================================================
296
+ // 6. 公钥恢复
297
+ // ==========================================================
298
+ describe('公钥恢复', function () {
299
+ it('recover: 可从签名恢复原公钥', function () {
300
+ const priv = secp.generatePrivateKey();
301
+ const pub = secp.publicKeyCreate(priv, true);
302
+ const msg = secp.generatePrivateKey();
303
+ const sig = secp.sign(msg, priv);
304
+
305
+ // 尝试 4 种 recovery id
306
+ let recovered = null;
307
+ for (let j = 0; j < 4; j++) {
308
+ const rec = secp.recover(msg, sig, j, true);
309
+ if (rec && hex(rec) === hex(pub)) {
310
+ recovered = rec;
311
+ break;
312
+ }
313
+ }
314
+ assert(recovered !== null, 'should recover the original public key');
315
+ });
316
+
317
+ it('recover: 无效签名返回 null', function () {
318
+ const msg = secp.generatePrivateKey();
319
+ const invalidSig = Buffer.alloc(70, 0xFF);
320
+ const result = secp.recover(msg, invalidSig, 0, true);
321
+ assert.strictEqual(result, null);
322
+ });
323
+ });
324
+
325
+ // ==========================================================
326
+ // 7. Tweak 操作
327
+ // ==========================================================
328
+ describe('Tweak 操作', function () {
329
+ it('privateKeyTweakAdd: (key + tweak) % n', function () {
330
+ const priv = secp.generatePrivateKey();
331
+ const tweak = Buffer.from('0000000000000000000000000000000000000000000000000000000000000001', 'hex');
332
+ const tweaked = secp.privateKeyTweakAdd(priv, tweak);
333
+ assert.strictEqual(tweaked.length, 32);
334
+ assert(secp.privateKeyVerify(tweaked));
335
+ // 加1后应该与原私钥不同(除非原私钥恰好是n-1)
336
+ if (hex(priv) !== 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364140') {
337
+ assert(!tweaked.equals(priv));
338
+ }
339
+ });
340
+
341
+ it('publicKeyTweakAdd: G * tweak + pubkey', function () {
342
+ const priv = secp.generatePrivateKey();
343
+ const pub = secp.publicKeyCreate(priv, true);
344
+ const tweak = Buffer.from('0000000000000000000000000000000000000000000000000000000000000001', 'hex');
345
+
346
+ const tweakedPub = secp.publicKeyTweakAdd(pub, tweak, true);
347
+ assert.strictEqual(tweakedPub.length, 33);
348
+ assert(secp.publicKeyVerify(tweakedPub));
349
+
350
+ // 验证:手动加1后私钥的公钥应等于原公钥加G
351
+ const tweakedPriv = secp.privateKeyTweakAdd(priv, tweak);
352
+ const expectedPub = secp.publicKeyCreate(tweakedPriv, true);
353
+ assert.strictEqual(hex(tweakedPub), hex(expectedPub),
354
+ 'publicKeyTweakAdd result should match privateKeyTweakAdd + publicKeyCreate');
355
+ });
356
+ });
357
+
358
+ // ==========================================================
359
+ // 8. binding 常量
360
+ // ==========================================================
361
+ describe('常量', function () {
362
+ it('binding: 始终为 false (非native)', function () {
363
+ assert.strictEqual(secp.binding, false);
364
+ });
365
+ });
366
+
367
+ // ==========================================================
368
+ // 9. verifyData + secret 集成测试
369
+ // ==========================================================
370
+ describe('上层集成: verifyData & Secret', function () {
371
+ const verifyData = require('../../src/utils/verifyData');
372
+ const Secret = require('../../src/utils/secret');
373
+
374
+ it('generateKey → signObj → verifyObj: 完整流程', function () {
375
+ const keys = verifyData.generateKey();
376
+ assert.strictEqual(typeof keys.private, 'string');
377
+ assert.strictEqual(typeof keys.public, 'string');
378
+ assert.strictEqual(keys.private.length, 64); // hex of 32 bytes
379
+ assert.strictEqual(keys.public.length, 66); // hex of 33 bytes (compressed)
380
+
381
+ const obj = { action: 'transfer', amount: 100, to: 'abc' };
382
+ const sig = verifyData.signObj(obj, keys.private);
383
+ assert.strictEqual(typeof sig, 'string');
384
+
385
+ const ok = verifyData.verifyObj(obj, sig, keys.public);
386
+ assert.strictEqual(ok, true);
387
+ });
388
+
389
+ it('generateKey: 用已知私钥生成公钥', function () {
390
+ const privHex = '0000000000000000000000000000000000000000000000000000000000000001';
391
+ const keys = verifyData.generateKey(privHex);
392
+ assert.strictEqual(keys.private, privHex);
393
+ // 压缩公钥,33字节 hex = 66 chars
394
+ assert.strictEqual(keys.public.length, 66);
395
+ });
396
+
397
+ it('verifyObj: 错误签名应失败', function () {
398
+ const keysA = verifyData.generateKey();
399
+ const keysB = verifyData.generateKey();
400
+ const obj = { msg: 'test' };
401
+ const sig = verifyData.signObj(obj, keysA.private);
402
+ // 用B的公钥验证A的签名 → 应该失败
403
+ const ok = verifyData.verifyObj(obj, sig, keysB.public);
404
+ assert.strictEqual(ok, false);
405
+ });
406
+
407
+ it('verifyObj: 篡改消息应失败', function () {
408
+ const keys = verifyData.generateKey();
409
+ const obj = { msg: 'test' };
410
+ const sig = verifyData.signObj(obj, keys.private);
411
+ const tampered = { msg: 'hacked' };
412
+ const ok = verifyData.verifyObj(tampered, sig, keys.public);
413
+ assert.strictEqual(ok, false);
414
+ });
415
+
416
+ it('Secret: 创建、握手、获取公钥', function () {
417
+ const secret = new Secret();
418
+ const pub = secret.input.getPublicKey();
419
+ assert(Buffer.isBuffer(pub));
420
+ assert.strictEqual(pub.length, 33);
421
+
422
+ const priv = secret.input.privateKey;
423
+ assert(Buffer.isBuffer(priv));
424
+ assert.strictEqual(priv.length, 32);
425
+ assert(secp.privateKeyVerify(priv));
426
+ });
427
+
428
+ it('Secret: 双方握手后共享密钥一致', function () {
429
+ const alice = new Secret();
430
+ const bob = new Secret();
431
+
432
+ const alicePub = alice.input.getPublicKey();
433
+ const bobPub = bob.input.getPublicKey();
434
+
435
+ alice.input.init(bobPub);
436
+ bob.output.init(alicePub);
437
+
438
+ // 双方应完成 ECDH
439
+ assert.strictEqual(alice.input.sid.length, 32);
440
+ assert.strictEqual(bob.output.sid.length, 32);
441
+ });
442
+ });
443
+
444
+ });
package/webpack.config.js CHANGED
@@ -13,13 +13,14 @@ module.exports = {
13
13
  },
14
14
  globalObject: 'typeof self !== \'undefined\' ? self : this',
15
15
  },
16
+ target: 'web',
16
17
  resolve: {
17
18
  // webpack 5: 为浏览器环境提供 Node.js 核心模块 polyfill
18
19
  fallback: {
19
20
  buffer: require.resolve('buffer/'),
20
21
  assert: require.resolve('assert/build/assert'),
21
22
  stream: require.resolve('stream-browserify'),
22
- crypto: require.resolve('crypto-browserify'),
23
+ crypto: false, // let @noble/* use globalThis.crypto (Web Crypto API in browsers)
23
24
  util: require.resolve('util/'),
24
25
  events: require.resolve('events/'),
25
26
  url: require.resolve('url/'),
@@ -43,5 +44,4 @@ module.exports = {
43
44
  process: 'process/browser',
44
45
  }),
45
46
  ],
46
- target: 'web',
47
47
  };
package/.babelrc DELETED
@@ -1,16 +0,0 @@
1
- {
2
- "presets": [
3
- ["env"],
4
- ["es2015", { "modules": false }],
5
- ["stage-2"]
6
- ],
7
- "plugins": [[
8
- "transform-runtime",
9
- {
10
- "helpers": false,
11
- "polyfill": false,
12
- "regenerator": true,
13
- "moduleName": "babel-runtime"
14
- }
15
- ]]
16
- }
@@ -1,142 +0,0 @@
1
- # gamerpc 版本演进分析 (V6.0.6 → V7.1.2 → V8.0.8)
2
-
3
- > 分析日期:2026-07-15
4
-
5
- ## Git 仓库地址
6
-
7
- - **当前 remote**: `https://gitee.com/bianque/gamegoldtoolkit.git`
8
- - **package.json 中标注**: `https://github.com/bookmansoft/gamegoldtoolkit`
9
-
10
- 两个地址可能指向同一仓库(镜像),或 GitHub 为原始仓库、Gitee 为镜像。
11
-
12
- ---
13
-
14
- ## 版本概览
15
-
16
- | 版本 | Commit | 日期 | 提交信息 |
17
- |------|--------|------|----------|
18
- | V6.0.6 | `1c9fabd` | 2021-07-03 | 6.0.6 |
19
- | V7.1.2 | `f5ba0e3` | 2023-11-14 | 7.1.2 |
20
- | V8.0.8 | `d80155e` | 2024-02-03 | RPC更新: 支持HTTPS切换 |
21
-
22
- ---
23
-
24
- ## V6.0.6 — 双连接器架构
25
-
26
- **时间**:2021-07-03
27
-
28
- **架构:双轨并行**
29
-
30
- ```
31
- toolkit.conn → authConn.js (主网/区块链全节点连接器)
32
- toolkit.gameconn → gameConn.js (游戏云服务器连接器)
33
- ```
34
-
35
- **特征**:
36
- - `index.js` 同时导出两个独立的连接器类
37
- - 工具函数(`encrypt`、`decrypt`、`signObj`、`verifyObj`、`hash256` 等)在 `index.js` 中**统一**往两个连接器的 `prototype` 上挂载
38
- - `authConn.js` 的注释是"访问游戏金节点的远程调用函数",区块链节点当时被称为"游戏金节点"
39
- - **同时兼容游戏连接器和区块链连接器**的全功能版本
40
-
41
- ---
42
-
43
- ## V7.1.2 — 工具函数内聚 + 浏览器兼容
44
-
45
- **时间**:2023-11-14
46
-
47
- **V6.0.6 → V7.1.2 变化**(4 个提交,85 行增/57 行删):
48
-
49
- ### V7.0.0 变更 (2021-09-03)
50
- 配合 Vallnet 2.0 使用:
51
-
52
- | 变更 | 说明 |
53
- |------|------|
54
- | 工具函数挂载方式重构 | 从 `index.js` 统一挂载改为各模块内部自行挂载。`authConn.js` 和 `gameConn.js` 各自 import 并挂载工具函数到 prototype,`index.js` 中删除对应的挂载代码 |
55
- | 注释更新 | `authConn.js` 注释从"访问游戏金节点"改为"访问全节点"——概念泛化 |
56
- | 新增验证模式 | `gameConn.js` 新增 `bxs` 验证模式支持 |
57
-
58
- ### V7.1.x 变更
59
-
60
- | 变更 | 说明 |
61
- |------|------|
62
- | 认证流程调整 | `gameConn.js` 中登录验证模式从 `domain` 字段改为用 `openid` 字段做路由判断 |
63
- | 浏览器兼容 | 引入本地 `src/utils/socket.io.min.js`,`gameConn` 改用此本地文件而非 npm 包的 `io`——解决浏览器环境兼容问题 |
64
- | Node.js 兼容 | build 命令添加 `NODE_OPTIONS=--openssl-legacy-provider`,解决新版 Node.js 的 OpenSSL 3.0 兼容问题 |
65
- | 主入口变更 | `main` 从 `index.js` 改为打包产物 `./lib/gamerpc7.1.2.js` |
66
-
67
- ---
68
-
69
- ## V8.0.8 — 大合并:偏重游戏云,去除区块链
70
-
71
- **时间**:2024-02-03
72
-
73
- **V7.1.2 → V8.0.8 变化**(5 个提交,902 行增/1515 行删):
74
-
75
- ### V8.0.3 — 初步精简 (2023-11-15)
76
-
77
- - `index.js` 中**注释掉大量区块链相关工具函数**的导出:
78
- `encrypt`、`decrypt`、`verifyData`、`generateKey`、`signObj`、`verifyObj`、`verifyAddress`、`hash256`、`hash160`、`sha1`、`Secret`、`createHmac`
79
- - `gameConn.js` 内部同样注释掉对应工具函数的 import 和挂载
80
- - **移除 `toolkit.conn` 导出**——区块链连接器不再对外暴露,只保留 `toolkit.gameconn`
81
- - `gameConn` 中 socket 连接从本地 `ioclient` 回归 npm 包 `io`
82
-
83
- ### V8.0.5 — util.js 重构
84
-
85
- - `src/utils/util.js` 大幅重构,精简约 62 行代码
86
-
87
- ### V8.0.6 — 清理本地 socket.io
88
-
89
- - **删除 `src/utils/socket.io.min.js`**——不再本地内嵌 socket.io,完全回归 npm 依赖
90
-
91
- ### V8.0.7 — 彻底合并
92
-
93
- - **删除 `src/authConn.js`**(595行)——全节点/区块链连接器代码彻底移除
94
- - **删除 `src/gameConn.js`**(705行)——游戏云连接器代码移除
95
- - 所有连接器逻辑合并入 `src/index.js`,变成一个统一的 `Remote` 类(约 700 行)
96
- - 出口从 `exports` 对象变为 `module.exports = Remote`(单一类导出)
97
- - 注释掉 `assert`、`encrypt`、`decrypt`、`verifyData` 等区块链相关工具的挂载
98
-
99
- ### V8.0.8 — 支持 HTTPS 切换
100
-
101
- - `createSocket` 不再接受 ip/port 参数,改为完全从 `this.config.webserver` 读取
102
- - 新增 `url` 字段支持:当 `config.webserver.url` 存在时直接使用完整 URL
103
- - `ws://host:port` → 直接使用 `wss://url`
104
- - `http://host:port` → 直接使用 `https://url`
105
- - 支持通过配置切换 HTTP/HTTPS、WS/WSS,适配 CDN/反向代理场景
106
- - `locate` 函数新增 `url` 参数:`locate(host, port, url)`
107
- - `getRequest` / `postRequest` 中 URL 拼接逻辑引入 `url` 优先策略
108
- - **删除 `getOpenId` 方法**——微信相关 OpenId 转换认证流程被移除
109
- - 删除 `login` 流程中微信 OpenId 转换的检测步骤
110
- - 在 README 中补充页面嵌入模式的使用说明
111
-
112
- ---
113
-
114
- ## 演进总览
115
-
116
- | 维度 | V6.0.6 | V7.1.2 | V8.0.8 |
117
- |------|--------|--------|--------|
118
- | **连接器数量** | 2 个(区块链 + 游戏云) | 2 个 | 1 个(仅游戏云) |
119
- | **区块链支持** | 完整支持 | 保留但内聚 | **已移除** |
120
- | **工具函数** | index.js 统一挂载 | 各自模块内部挂载 | 大量注释掉,只保留 `stringify`/`CommMode` 等基础 |
121
- | **出口方式** | `toolkit.conn` + `toolkit.gameconn` | 同左 | `module.exports = Remote` |
122
- | **socket 连接方式** | npm `io` | 浏览器兼容的本地文件 | npm `io` + 支持 URL/HTTPS |
123
- | **连接地址模式** | `host:port` 组合 | `host:port` 组合 | `host:port` 或完整 `url` |
124
- | **核心偏重** | 双轨并行 | 双轨,认证流程微调 | **明确偏重游戏云** |
125
- | **认证流程** | domain 路由 + 微信 | openid 路由 + bxs 模式 | 简化,移除微信 OpenId 转换 |
126
- | **文件数量** | index + authConn + gameConn | index + authConn + gameConn + socket.io.min | **仅 index.js(Remote 类)** |
127
-
128
- ## 结论
129
-
130
- 项目最初(V6)是**同时兼容游戏连接器和区块链连接器**的双轨设计,通过 `toolkit.conn` 和 `toolkit.gameconn` 分别提供两个独立的连接器实例。
131
-
132
- **V7 是一个过渡版本**,主要解决两类兼容问题:
133
- 1. **浏览器环境兼容**:引入本地 socket.io 文件替代 npm 包的动态加载
134
- 2. **Node.js OpenSSL 3.0 兼容**:build 命令中增加 `--openssl-legacy-provider`
135
-
136
- **V8 是一次彻底的重构**,明确了项目的定位调整:
137
- 1. 将双连接器合并为单一 `Remote` 类
138
- 2. **物理删除 `authConn.js`(全节点/区块链连接器)**,大量注释/删除区块链相关的加密签名工具函数
139
- 3. 新增 HTTPS/WSS 的 URL 模式支持,适配现代部署场景(CDN、反向代理)
140
- 4. 简化认证流程,移除微信 OpenId 转换逻辑
141
-
142
- 整个项目从"通用连接器工具箱"演变为**专注于游戏云连接**的轻量级 RPC 客户端。
package/test/game/kow.js DELETED
@@ -1,43 +0,0 @@
1
- /**
2
- * 联机单元测试:游戏登录测试流程
3
- */
4
-
5
- //连接配置信息
6
- const config = {
7
- UrlHead: "http", //协议选择: http/https
8
- webserver: {
9
- "host": "127.0.0.1", //远程主机地址
10
- "port": 9901 //远程主机端口
11
- },
12
- logicserver: {},
13
- oemInfo: { //模拟用户信息
14
- domain: 'CoreOfKow', //指定访问的逻辑服务器类型
15
- openid: `bxs.15699999936`, //用户标识
16
- token: '', //用户令牌,由920客户端向920服务端索取并填充于此
17
- },
18
- }
19
-
20
- //长连接中,下行通告的类型定义
21
- const NotifyType = {
22
- action: 1, //体力数值推送
23
- };
24
-
25
- //引入长连接组件
26
- let gameconn = require('../../index');
27
- let connector = new gameconn(config)
28
- .setFetch(require('node-fetch')); //设置node服务端环境下兼容的fetch函数,**注意只在node服务端环境下需要,浏览器环境中系统自带 fetch 函数**
29
-
30
- connector.setmode(connector.CommMode.ws).watch(msg => {
31
- console.log('收到下行消息', msg);
32
- }, NotifyType.action);
33
-
34
- (async function() {
35
- console.log('start login...');
36
- try {
37
- let ret = await connector.login(config.oemInfo);
38
- console.log('end login...');
39
- console.log(config.oemInfo, ret);
40
- } catch(e) {
41
- console.log(e);
42
- }
43
- })();